struct SOSEHInfo
{
-#ifndef FEATURE_CORECLR
- __field_ecount(EHCount)
-#endif
DACEHInfo *m_pInfos;
UINT EHCount;
CLRDATA_ADDRESS methodStart;
#include "safemath.h"
-#ifdef _ASSERTE
#undef _ASSERTE
-#endif
-#ifndef _ASSERTE
#ifdef _DEBUG
#define _ASSERTE(expr) \
do { if (!(expr) ) { ExtErr("_ASSERTE fired:\n\t%s\n", #expr); if (IsDebuggerPresent()) DebugBreak(); } } while (0)
#else
#define _ASSERTE(x)
#endif
-#endif // ASSERTE
inline size_t ALIGN_DOWN( size_t val, size_t alignment )
{
#include "gcdesc.h"
-#ifdef _ASSERTE
#undef _ASSERTE
-#endif
namespace sos
{
EX_TRY
{
ReleaseHolder<BINDER_SPACE::Assembly> pAsm;
-#ifdef FEATURE_CORECLR
StackSString systemPath(SystemDomain::System()->SystemDirectory());
hr = AssemblyBinder::BindToSystem(systemPath, &pAsm, fBindToNativeImage);
-#else
- AssemblySpec::BindToSystem(&pAsm);
-#endif
if(SUCCEEDED(hr))
{
_ASSERTE(pAsm != NULL);
// TODO: We also should check for type/member visibility here. To do that we can replace
// the following chunk of code with a simple InvokeUtil::CanAccessClass call.
// But it's too late to make this change in Dev10 and we want SL4 to be compatible with Dev10.
-#ifndef FEATURE_CORECLR
- // Make sure security allows us access to the array type - if it is critical, convert that to a
- // demand for full trust
- if (!SecurityStackWalk::HasFlagsOrFullyTrusted(0))
- {
- if (Security::TypeRequiresTransparencyCheck(pMT, true))
- {
- // If we're creating a critical type, convert the critical check into a demand for full trust
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_FULL_TRUST);
- }
- }
-#else
if (Security::TypeRequiresTransparencyCheck(pMT))
{
// The AccessCheckOptions flag doesn't matter because we just need to get the caller.
accessCheckOptions.DemandMemberAccessOrFail(&sCtx, pMT, FALSE /*visibilityCheck*/);
}
-#endif // !FEATURE_CORECLR
// Check for byref-like types.
if (pMT->IsByRefLike())
STRINGREF sZero=NULL;
// @TODO what if not sequential?
-#ifndef FEATURE_CORECLR
- if (numfmt->iDigitSubstitution == 2) // native digits
- {
- PTRARRAYREF aDigits = numfmt->sNativeDigits;
- if (aDigits!=NULL && aDigits->GetNumComponents()>0)
- sZero=(STRINGREF)aDigits->GetAt(0);
- }
-#endif
// Do the worst case calculation
/* US English - for Double.MinValue.ToString("C99"); we require 514 characters
}
FCIMPLEND
-#if !defined(FEATURE_CORECLR)
-//
-// Used by base types that are not in mscorlib.dll (such as System.Numerics.BigInteger in System.Core.dll)
-// Note that the allDigits buffer must be fixed across this call or you will introduce a GC Hole.
-//
-FCIMPL4(Object*, COMNumber::FormatNumberBuffer, BYTE* number, StringObject* formatUNSAFE, NumberFormatInfo* numfmtUNSAFE, __in_z wchar_t* allDigits)
-{
- FCALL_CONTRACT;
-
- wchar fmt;
- int digits;
- NUMBER* pNumber;
-
- struct _gc
- {
- STRINGREF refFormat;
- NUMFMTREF refNumFmt;
- STRINGREF refRetString;
- } gc;
-
- gc.refFormat = ObjectToSTRINGREF(formatUNSAFE);
- gc.refNumFmt = (NUMFMTREF)numfmtUNSAFE;
- gc.refRetString = NULL;
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
- if (gc.refNumFmt == 0) COMPlusThrowArgumentNull(W("NumberFormatInfo"));
-
- pNumber = (NUMBER*) number;
-
- pNumber->allDigits = allDigits;
-
- fmt = ParseFormatSpecifier(gc.refFormat, &digits);
- if (fmt != 0) {
- gc.refRetString = NumberToString(pNumber, fmt, digits, gc.refNumFmt);
- }
- else {
- gc.refRetString = NumberToStringFormat(pNumber, gc.refFormat, gc.refNumFmt);
- }
- HELPER_METHOD_FRAME_END();
-
- return OBJECTREFToObject(gc.refRetString);
-}
-FCIMPLEND
-
-#endif // !FEATURE_CORECLR
FCIMPL2(FC_BOOL_RET, COMNumber::NumberBufferToDecimal, BYTE* number, DECIMAL* value)
{
static FCDECL3(Object*, FormatUInt32, UINT32 value, StringObject* formatUNSAFE, NumberFormatInfo* numfmtUNSAFE);
static FCDECL3_VII(Object*, FormatInt64, INT64 value, StringObject* formatUNSAFE, NumberFormatInfo* numfmtUNSAFE);
static FCDECL3_VII(Object*, FormatUInt64, UINT64 value, StringObject* formatUNSAFE, NumberFormatInfo* numfmtUNSAFE);
-#if !defined(FEATURE_CORECLR)
- static FCDECL4(Object*, FormatNumberBuffer, BYTE* number, StringObject* formatUNSAFE, NumberFormatInfo* numfmtUNSAFE, __in_z wchar_t* allDigits);
-#endif // !FEATURE_CORECLR
static FCDECL2(FC_BOOL_RET, NumberBufferToDecimal, BYTE* number, DECIMAL* value);
static FCDECL2(FC_BOOL_RET, NumberBufferToDouble, BYTE* number, double* value);
inline COMNlsHashProvider * GetCurrentNlsHashProvider()
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
- return curDomain->m_pNlsHashProvider;
-#else
return &COMNlsHashProvider::s_NlsHashProvider;
-#endif // FEATURE_CORECLR
}
FCIMPL3(INT32, COMString::Marvin32HashString, StringObject* thisRefUNSAFE, INT32 strLen, INT64 additionalEntropy) {
#include "array.h"
#include "eepolicy.h"
-#if !defined(FEATURE_CORECLR)
-#include "metahost.h"
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_WINDOWSPHONE
Volatile<BOOL> g_fGetPhoneVersionInitialized;
-#ifndef FEATURE_CORECLR
-INT64 QCALLTYPE SystemNative::GetWorkingSet()
-{
- QCALL_CONTRACT;
-
- DWORD memUsage = 0;
-
- BEGIN_QCALL;
- memUsage = WszGetWorkingSet();
- END_QCALL;
-
- return memUsage;
-}
-#endif // !FEATURE_CORECLR
VOID QCALLTYPE SystemNative::Exit(INT32 exitcode)
{
}
FCIMPLEND
-#ifndef FEATURE_CORECLR
-
-void QCALLTYPE SystemNative::_GetSystemVersion(QCall::StringHandleOnStack retVer)
-{
- QCALL_CONTRACT;
- BEGIN_QCALL;
-
- WCHAR wszVersion[_MAX_PATH];
- DWORD dwVersion = _MAX_PATH;
-
- // Get the version
- IfFailThrow(g_pCLRRuntime->GetVersionString(wszVersion, &dwVersion));
- retVer.Set(wszVersion);
-
- END_QCALL;
-}
-
-#endif
INT32 QCALLTYPE SystemNative::GetProcessorCount()
{
BEGIN_QCALL;
-#ifdef FEATURE_CORECLR
IfFailThrow(E_NOINTERFACE);
-#else
- HRESULT hr = g_pCLRRuntime->GetInterface(clsid, riid, &pUnk);
-
- if (FAILED(hr))
- hr = g_pCLRRuntime->QueryInterface(riid, &pUnk);
-
- IfFailThrow(hr);
-#endif
END_QCALL;
#ifndef FEATURE_PAL
// If we have the exception object, then try to setup
// the watson bucket if it has any details.
-#ifdef FEATURE_CORECLR
// On CoreCLR, Watson may not be enabled. Thus, we should
// skip this, if required.
if (IsWatsonEnabled())
-#endif // FEATURE_CORECLR
{
BEGIN_SO_INTOLERANT_CODE(pThread);
if ((gc.refExceptionForWatsonBucketing == NULL) || !SetupWatsonBucketsForFailFast(gc.refExceptionForWatsonBucketing))
FCIMPLEND
-#ifndef FEATURE_CORECLR
-BOOL QCALLTYPE SystemNative::IsCLRHosted()
-{
- QCALL_CONTRACT;
-
- BOOL retVal = false;
- BEGIN_QCALL;
- retVal = (CLRHosted() & CLRHOSTED) != 0;
- END_QCALL;
-
- return retVal;
-}
-
-void QCALLTYPE SystemNative::TriggerCodeContractFailure(ContractFailureKind failureKind, LPCWSTR pMessage, LPCWSTR pCondition, LPCWSTR exceptionAsString)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- GCX_COOP();
-
- EEPolicy::HandleCodeContractFailure(pMessage, pCondition, exceptionAsString);
- // Note: if the host chose to throw an exception, we've returned from this method and
- // will throw that exception in managed code, because it's easier to pass the right parameters there.
-
- END_QCALL;
-}
-#endif // !FEATURE_CORECLR
FCIMPL0(FC_BOOL_RET, SystemNative::IsServerGC)
{
FCIMPLEND
-#ifndef FEATURE_CORECLR
-//
-// SystemNative::LegacyFormatMode - Fcall implementation for System.TimeSpan.LegacyFormatMode
-// checks for the DWORD "TimeSpan_LegacyFormatMode" CLR config option
-//
-FCIMPL0(FC_BOOL_RET, SystemNative::LegacyFormatMode)
-{
- FCALL_CONTRACT;
-
- DWORD flag = 0;
-
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
- flag = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_TimeSpan_LegacyFormatMode);
- END_SO_INTOLERANT_CODE;
-
- if (flag)
- FC_RETURN_BOOL(TRUE);
- else
- FC_RETURN_BOOL(FALSE);
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
-#ifndef FEATURE_CORECLR
-//
-// SystemNative::CheckLegacyManagedDeflateStream - Fcall implementation for System.IO.Compression.DeflateStream
-// checks for the DWORD "NetFx45_LegacyManagedDeflateStream" CLR config option
-//
-// Move this into a separate CLRConfigQCallWrapper class once CLRConfig has been refactored!
-//
-FCIMPL0(FC_BOOL_RET, SystemNative::CheckLegacyManagedDeflateStream)
-{
- FCALL_CONTRACT;
-
- DWORD flag = 0;
-
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
- flag = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_NetFx45_LegacyManagedDeflateStream);
- END_SO_INTOLERANT_CODE;
-
- if (flag)
- FC_RETURN_BOOL(TRUE);
- else
- FC_RETURN_BOOL(FALSE);
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
-
-#ifndef FEATURE_CORECLR
-//
-// SystemNative::CheckThrowUnobservedTaskExceptions - Fcall implementation for System.Threading.Tasks.TaskExceptionHolder
-// checks for the DWORD "ThrowUnobservedTaskExceptions" CLR config option
-//
-FCIMPL0(FC_BOOL_RET, SystemNative::CheckThrowUnobservedTaskExceptions)
-{
- FCALL_CONTRACT;
-
- DWORD flag = 0;
-
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
- flag = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_ThrowUnobservedTaskExceptions);
- END_SO_INTOLERANT_CODE;
-
- if (flag)
- FC_RETURN_BOOL(TRUE);
- else
- FC_RETURN_BOOL(FALSE);
-}
-FCIMPLEND
-
-BOOL QCALLTYPE SystemNative::LegacyDateTimeParseMode()
-{
- QCALL_CONTRACT;
-
- BOOL retVal = false;
- BEGIN_QCALL;
- retVal = (BOOL) CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DateTime_NetFX35ParseMode);
- END_QCALL;
-
- return retVal;
-}
-
-//
-// This method used with DateTimeParse to fix the parsing of AM/PM like "1/10 5 AM" case
-//
-BOOL QCALLTYPE SystemNative::EnableAmPmParseAdjustment()
-{
- QCALL_CONTRACT;
-
- BOOL retVal = false;
- BEGIN_QCALL;
- retVal = (BOOL) CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DateTime_NetFX40AmPmParseAdjustment);
- END_QCALL;
-
- return retVal;
-}
-
-#endif // !FEATURE_CORECLR
static FCDECL1(FC_BOOL_RET, GetOSVersion, OSVERSIONINFOObject *osVer);
static FCDECL1(FC_BOOL_RET, GetOSVersionEx, OSVERSIONINFOEXObject *osVer);
-#ifndef FEATURE_CORECLR
- static
- INT64 QCALLTYPE GetWorkingSet();
-#endif // !FEATURE_CORECLR
static
void QCALLTYPE Exit(INT32 exitcode);
static FCDECL1(VOID, FailFast, StringObject* refMessageUNSAFE);
static FCDECL2(VOID, FailFastWithExitCode, StringObject* refMessageUNSAFE, UINT exitCode);
static FCDECL2(VOID, FailFastWithException, StringObject* refMessageUNSAFE, ExceptionObject* refExceptionUNSAFE);
-#ifndef FEATURE_CORECLR
- static void QCALLTYPE TriggerCodeContractFailure(ContractFailureKind failureKind, LPCWSTR pMessage, LPCWSTR pCondition, LPCWSTR exceptionAsText);
- static BOOL QCALLTYPE IsCLRHosted();
-#endif // !FEATURE_CORECLR
static FCDECL0(StringObject*, GetDeveloperPath);
static FCDECL1(Object*, _GetEnvironmentVariable, StringObject* strVar);
// Return a method info for the method were the exception was thrown
static FCDECL1(ReflectMethodObject*, GetMethodFromStackTrace, ArrayBase* pStackTraceUNSAFE);
-#ifndef FEATURE_CORECLR
- // Functions on the System.TimeSpan class
- static FCDECL0(FC_BOOL_RET, LegacyFormatMode);
- // Function on the DateTime
- static BOOL QCALLTYPE EnableAmPmParseAdjustment();
- static BOOL QCALLTYPE LegacyDateTimeParseMode();
-#endif // !FEATURE_CORECLR
// Move this into a separate CLRConfigQCallWrapper class once CLRConfif has been refactored:
-#ifndef FEATURE_CORECLR
- static FCDECL0(FC_BOOL_RET, CheckLegacyManagedDeflateStream);
-#endif // !FEATURE_CORECLR
-#ifndef FEATURE_CORECLR
- static FCDECL0(FC_BOOL_RET, CheckThrowUnobservedTaskExceptions);
-#endif // !FEATURE_CORECLR
private:
// Common processing code for FailFast
static BOOL QCALLTYPE InternalGetSystemDefaultUILanguage(QCall::StringHandleOnStack systemDefaultUiLanguage);
// Added but disabled from desktop in .NET 4.0, stayed disabled in .NET 4.5
-#ifdef FEATURE_CORECLR
static FCDECL0(Object*, nativeGetResourceFallbackArray);
-#endif
//
// Native helper functions for methods in DateTimeFormatInfo
static INT_PTR QCALLTYPE InternalInitSortHandle(LPCWSTR localeName, INT_PTR* handleOrigin);
static INT_PTR InitSortHandleHelper(LPCWSTR localeName, INT_PTR* handleOrigin);
static INT_PTR InternalInitOsSortHandle(LPCWSTR localeName, INT_PTR* handleOrigin);
-#ifndef FEATURE_CORECLR
- static INT_PTR InternalInitVersionedSortHandle(LPCWSTR localeName, INT_PTR* handleOrigin);
- static INT_PTR InternalInitVersionedSortHandle(LPCWSTR localeName, INT_PTR* handleOrigin, DWORD sortVersion);
- static DWORD QCALLTYPE InternalGetSortVersion();
-#endif
static BOOL QCALLTYPE InternalGetNlsVersionEx(INT_PTR handle, INT_PTR handleOrigin, LPCWSTR lpLocaleName, NLSVERSIONINFOEX * lpVersionInformation);
//
//
// Please KEEP this table SORTED ALPHABETICALLY! We do a binary search on this array.
const EncodingDataItem COMNlsInfo::EncodingDataTable[] = {
-#ifdef FEATURE_CORECLR
// encoding name, codepage.
{"ANSI_X3.4-1968", 20127 },
{"ANSI_X3.4-1986", 20127 },
{"x-unicode-1-1-utf-8", 65001 },
{"x-unicode-2-0-utf-7", 65000 },
{"x-unicode-2-0-utf-8", 65001 },
-#else
- // Total Items: 455
-// encoding name, codepage.
-{"437", 437},
-{"ANSI_X3.4-1968", 20127},
-{"ANSI_X3.4-1986", 20127},
-// {L"_autodetect", 50932},
-// {L"_autodetect_all", 50001},
-// {L"_autodetect_kr", 50949},
-{"arabic", 28596},
-{"ascii", 20127},
-{"ASMO-708", 708},
-{"Big5", 950},
-{"Big5-HKSCS", 950},
-{"CCSID00858", 858},
-{"CCSID00924", 20924},
-{"CCSID01140", 1140},
-{"CCSID01141", 1141},
-{"CCSID01142", 1142},
-{"CCSID01143", 1143},
-{"CCSID01144", 1144},
-{"CCSID01145", 1145},
-{"CCSID01146", 1146},
-{"CCSID01147", 1147},
-{"CCSID01148", 1148},
-{"CCSID01149", 1149},
-{"chinese", 936},
-{"cn-big5", 950},
-{"CN-GB", 936},
-{"CP00858", 858},
-{"CP00924", 20924},
-{"CP01140", 1140},
-{"CP01141", 1141},
-{"CP01142", 1142},
-{"CP01143", 1143},
-{"CP01144", 1144},
-{"CP01145", 1145},
-{"CP01146", 1146},
-{"CP01147", 1147},
-{"CP01148", 1148},
-{"CP01149", 1149},
-{"cp037", 37},
-{"cp1025", 21025},
-{"CP1026", 1026},
-{"cp1256", 1256},
-{"CP273", 20273},
-{"CP278", 20278},
-{"CP280", 20280},
-{"CP284", 20284},
-{"CP285", 20285},
-{"cp290", 20290},
-{"cp297", 20297},
-{"cp367", 20127},
-{"cp420", 20420},
-{"cp423", 20423},
-{"cp424", 20424},
-{"cp437", 437},
-{"CP500", 500},
-{"cp50227", 50227},
- //{L"cp50229", 50229},
-{"cp819", 28591},
-{"cp850", 850},
-{"cp852", 852},
-{"cp855", 855},
-{"cp857", 857},
-{"cp858", 858},
-{"cp860", 860},
-{"cp861", 861},
-{"cp862", 862},
-{"cp863", 863},
-{"cp864", 864},
-{"cp865", 865},
-{"cp866", 866},
-{"cp869", 869},
-{"CP870", 870},
-{"CP871", 20871},
-{"cp875", 875},
-{"cp880", 20880},
-{"CP905", 20905},
-//{L"cp930", 50930},
-//{L"cp933", 50933},
-//{L"cp935", 50935},
-//{L"cp937", 50937},
-//{L"cp939", 50939},
-{"csASCII", 20127},
-{"csbig5", 950},
-{"csEUCKR", 51949},
-{"csEUCPkdFmtJapanese", 51932},
-{"csGB2312", 936},
-{"csGB231280", 936},
-{"csIBM037", 37},
-{"csIBM1026", 1026},
-{"csIBM273", 20273},
-{"csIBM277", 20277},
-{"csIBM278", 20278},
-{"csIBM280", 20280},
-{"csIBM284", 20284},
-{"csIBM285", 20285},
-{"csIBM290", 20290},
-{"csIBM297", 20297},
-{"csIBM420", 20420},
-{"csIBM423", 20423},
-{"csIBM424", 20424},
-{"csIBM500", 500},
-{"csIBM870", 870},
-{"csIBM871", 20871},
-{"csIBM880", 20880},
-{"csIBM905", 20905},
-{"csIBMThai", 20838},
-{"csISO2022JP", 50221},
-{"csISO2022KR", 50225},
-{"csISO58GB231280", 936},
-{"csISOLatin1", 28591},
-{"csISOLatin2", 28592},
-{"csISOLatin3", 28593},
-{"csISOLatin4", 28594},
-{"csISOLatin5", 28599},
-{"csISOLatin9", 28605},
-{"csISOLatinArabic", 28596},
-{"csISOLatinCyrillic", 28595},
-{"csISOLatinGreek", 28597},
-{"csISOLatinHebrew", 28598},
-{"csKOI8R", 20866},
-{"csKSC56011987", 949},
-{"csPC8CodePage437", 437},
-{"csShiftJIS", 932},
-{"csUnicode11UTF7", 65000},
-{"csWindows31J", 932},
-{"cyrillic", 28595},
-{"DIN_66003", 20106},
-{"DOS-720", 720},
-{"DOS-862", 862},
-{"DOS-874", 874},
-{"ebcdic-cp-ar1", 20420},
-{"ebcdic-cp-be", 500},
-{"ebcdic-cp-ca", 37},
-{"ebcdic-cp-ch", 500},
-{"EBCDIC-CP-DK", 20277},
-{"ebcdic-cp-es", 20284},
-{"ebcdic-cp-fi", 20278},
-{"ebcdic-cp-fr", 20297},
-{"ebcdic-cp-gb", 20285},
-{"ebcdic-cp-gr", 20423},
-{"ebcdic-cp-he", 20424},
-{"ebcdic-cp-is", 20871},
-{"ebcdic-cp-it", 20280},
-{"ebcdic-cp-nl", 37},
-{"EBCDIC-CP-NO", 20277},
-{"ebcdic-cp-roece", 870},
-{"ebcdic-cp-se", 20278},
-{"ebcdic-cp-tr", 20905},
-{"ebcdic-cp-us", 37},
-{"ebcdic-cp-wt", 37},
-{"ebcdic-cp-yu", 870},
-{"EBCDIC-Cyrillic", 20880},
-{"ebcdic-de-273+euro", 1141},
-{"ebcdic-dk-277+euro", 1142},
-{"ebcdic-es-284+euro", 1145},
-{"ebcdic-fi-278+euro", 1143},
-{"ebcdic-fr-297+euro", 1147},
-{"ebcdic-gb-285+euro", 1146},
-{"ebcdic-international-500+euro", 1148},
-{"ebcdic-is-871+euro", 1149},
-{"ebcdic-it-280+euro", 1144},
-{"EBCDIC-JP-kana", 20290},
-{"ebcdic-Latin9--euro", 20924},
-{"ebcdic-no-277+euro", 1142},
-{"ebcdic-se-278+euro", 1143},
-{"ebcdic-us-37+euro", 1140},
-{"ECMA-114", 28596},
-{"ECMA-118", 28597},
-{"ELOT_928", 28597},
-{"euc-cn", 51936},
-{"euc-jp", 51932},
-{"euc-kr", 51949},
-{"Extended_UNIX_Code_Packed_Format_for_Japanese", 51932},
-{"GB18030", 54936},
-{"GB2312", 936},
-{"GB2312-80", 936},
-{"GB231280", 936},
-{"GBK", 936},
-{"GB_2312-80", 936},
-{"German", 20106},
-{"greek", 28597},
-{"greek8", 28597},
-{"hebrew", 28598},
-{"hz-gb-2312", 52936},
-{"IBM-Thai", 20838},
-{"IBM00858", 858},
-{"IBM00924", 20924},
-{"IBM01047", 1047},
-{"IBM01140", 1140},
-{"IBM01141", 1141},
-{"IBM01142", 1142},
-{"IBM01143", 1143},
-{"IBM01144", 1144},
-{"IBM01145", 1145},
-{"IBM01146", 1146},
-{"IBM01147", 1147},
-{"IBM01148", 1148},
-{"IBM01149", 1149},
-{"IBM037", 37},
-{"IBM1026", 1026},
-{"IBM273", 20273},
-{"IBM277", 20277},
-{"IBM278", 20278},
-{"IBM280", 20280},
-{"IBM284", 20284},
-{"IBM285", 20285},
-{"IBM290", 20290},
-{"IBM297", 20297},
-{"IBM367", 20127},
-{"IBM420", 20420},
-{"IBM423", 20423},
-{"IBM424", 20424},
-{"IBM437", 437},
-{"IBM500", 500},
-{"ibm737", 737},
-{"ibm775", 775},
-{"ibm819", 28591},
-{"IBM850", 850},
-{"IBM852", 852},
-{"IBM855", 855},
-{"IBM857", 857},
-{"IBM860", 860},
-{"IBM861", 861},
-{"IBM862", 862},
-{"IBM863", 863},
-{"IBM864", 864},
-{"IBM865", 865},
-{"IBM866", 866},
-{"IBM869", 869},
-{"IBM870", 870},
-{"IBM871", 20871},
-{"IBM880", 20880},
-{"IBM905", 20905},
-{"irv", 20105},
-{"ISO-10646-UCS-2", 1200},
-{"iso-2022-jp", 50220},
-{"iso-2022-jpeuc", 51932},
-{"iso-2022-kr", 50225},
-{"iso-2022-kr-7", 50225},
-{"iso-2022-kr-7bit", 50225},
-{"iso-2022-kr-8", 51949},
-{"iso-2022-kr-8bit", 51949},
-{"iso-8859-1", 28591},
-{"iso-8859-11", 874},
-{"iso-8859-13", 28603},
-{"iso-8859-15", 28605},
-{"iso-8859-2", 28592},
-{"iso-8859-3", 28593},
-{"iso-8859-4", 28594},
-{"iso-8859-5", 28595},
-{"iso-8859-6", 28596},
-{"iso-8859-7", 28597},
-{"iso-8859-8", 28598},
-{"ISO-8859-8 Visual", 28598},
-{"iso-8859-8-i", 38598},
-{"iso-8859-9", 28599},
-{"iso-ir-100", 28591},
-{"iso-ir-101", 28592},
-{"iso-ir-109", 28593},
-{"iso-ir-110", 28594},
-{"iso-ir-126", 28597},
-{"iso-ir-127", 28596},
-{"iso-ir-138", 28598},
-{"iso-ir-144", 28595},
-{"iso-ir-148", 28599},
-{"iso-ir-149", 949},
-{"iso-ir-58", 936},
-{"iso-ir-6", 20127},
-{"ISO646-US", 20127},
-{"iso8859-1", 28591},
-{"iso8859-2", 28592},
-{"ISO_646.irv:1991", 20127},
-{"iso_8859-1", 28591},
-{"ISO_8859-15", 28605},
-{"iso_8859-1:1987", 28591},
-{"iso_8859-2", 28592},
-{"iso_8859-2:1987", 28592},
-{"ISO_8859-3", 28593},
-{"ISO_8859-3:1988", 28593},
-{"ISO_8859-4", 28594},
-{"ISO_8859-4:1988", 28594},
-{"ISO_8859-5", 28595},
-{"ISO_8859-5:1988", 28595},
-{"ISO_8859-6", 28596},
-{"ISO_8859-6:1987", 28596},
-{"ISO_8859-7", 28597},
-{"ISO_8859-7:1987", 28597},
-{"ISO_8859-8", 28598},
-{"ISO_8859-8:1988", 28598},
-{"ISO_8859-9", 28599},
-{"ISO_8859-9:1989", 28599},
-{"Johab", 1361},
-{"koi", 20866},
-{"koi8", 20866},
-{"koi8-r", 20866},
-{"koi8-ru", 21866},
-{"koi8-u", 21866},
-{"koi8r", 20866},
-{"korean", 949},
-{"ks-c-5601", 949},
-{"ks-c5601", 949},
-{"KSC5601", 949},
-{"KSC_5601", 949},
-{"ks_c_5601", 949},
-{"ks_c_5601-1987", 949},
-{"ks_c_5601-1989", 949},
-{"ks_c_5601_1987", 949},
-{"l1", 28591},
-{"l2", 28592},
-{"l3", 28593},
-{"l4", 28594},
-{"l5", 28599},
-{"l9", 28605},
-{"latin1", 28591},
-{"latin2", 28592},
-{"latin3", 28593},
-{"latin4", 28594},
-{"latin5", 28599},
-{"latin9", 28605},
-{"logical", 28598},
-{"macintosh", 10000},
-{"ms_Kanji", 932},
-{"Norwegian", 20108},
-{"NS_4551-1", 20108},
-{"PC-Multilingual-850+euro", 858},
-{"SEN_850200_B", 20107},
-{"shift-jis", 932},
-{"shift_jis", 932},
-{"sjis", 932},
-{"Swedish", 20107},
-{"TIS-620", 874},
-{"ucs-2", 1200},
-{"unicode", 1200},
-{"unicode-1-1-utf-7", 65000},
-{"unicode-1-1-utf-8", 65001},
-{"unicode-2-0-utf-7", 65000},
-{"unicode-2-0-utf-8", 65001},
-// People get confused about the FFFE here. We can't change this because it'd break existing apps.
-// This has been this way for a long time, including in Mlang.
-{"unicodeFFFE", 1201}, // Big Endian, BOM seems backwards, think of the BOM in little endian order.
-{"us", 20127},
-{"us-ascii", 20127},
-{"utf-16", 1200},
-{"UTF-16BE", 1201},
-{"UTF-16LE", 1200},
-{"utf-32", 12000},
-{"UTF-32BE", 12001},
-{"UTF-32LE", 12000},
-{"utf-7", 65000},
-{"utf-8", 65001},
-{"visual", 28598},
-{"windows-1250", 1250},
-{"windows-1251", 1251},
-{"windows-1252", 1252},
-{"windows-1253", 1253},
-{"Windows-1254", 1254},
-{"windows-1255", 1255},
-{"windows-1256", 1256},
-{"windows-1257", 1257},
-{"windows-1258", 1258},
-{"windows-874", 874},
-{"x-ansi", 1252},
-{"x-Chinese-CNS", 20000},
-{"x-Chinese-Eten", 20002},
-{"x-cp1250", 1250},
-{"x-cp1251", 1251},
-{"x-cp20001", 20001},
-{"x-cp20003", 20003},
-{"x-cp20004", 20004},
-{"x-cp20005", 20005},
-{"x-cp20261", 20261},
-{"x-cp20269", 20269},
-{"x-cp20936", 20936},
-{"x-cp20949", 20949},
-{"x-cp50227", 50227},
-//{L"x-cp50229", 50229},
-//{L"X-EBCDIC-JapaneseAndUSCanada", 50931},
-{"X-EBCDIC-KoreanExtended", 20833},
-{"x-euc", 51932},
-{"x-euc-cn", 51936},
-{"x-euc-jp", 51932},
-{"x-Europa", 29001},
-{"x-IA5", 20105},
-{"x-IA5-German", 20106},
-{"x-IA5-Norwegian", 20108},
-{"x-IA5-Swedish", 20107},
-{"x-iscii-as", 57006},
-{"x-iscii-be", 57003},
-{"x-iscii-de", 57002},
-{"x-iscii-gu", 57010},
-{"x-iscii-ka", 57008},
-{"x-iscii-ma", 57009},
-{"x-iscii-or", 57007},
-{"x-iscii-pa", 57011},
-{"x-iscii-ta", 57004},
-{"x-iscii-te", 57005},
-{"x-mac-arabic", 10004},
-{"x-mac-ce", 10029},
-{"x-mac-chinesesimp", 10008},
-{"x-mac-chinesetrad", 10002},
-{"x-mac-croatian", 10082},
-{"x-mac-cyrillic", 10007},
-{"x-mac-greek", 10006},
-{"x-mac-hebrew", 10005},
-{"x-mac-icelandic", 10079},
-{"x-mac-japanese", 10001},
-{"x-mac-korean", 10003},
-{"x-mac-romanian", 10010},
-{"x-mac-thai", 10021},
-{"x-mac-turkish", 10081},
-{"x-mac-ukrainian", 10017},
-{"x-ms-cp932", 932},
-{"x-sjis", 932},
-{"x-unicode-1-1-utf-7", 65000},
-{"x-unicode-1-1-utf-8", 65001},
-{"x-unicode-2-0-utf-7", 65000},
-{"x-unicode-2-0-utf-8", 65001},
-{"x-x-big5", 950},
-
-#endif // FEATURE_CORECLR
};
//
const CodePageDataItem COMNlsInfo::CodePageDataTable[] = {
-#ifdef FEATURE_CORECLR
// Total Items:
// code page, family code page, web name, header name, body name, flags
MapCodePageDataItem( 65000, 1200, "utf-7", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS), // "Unicode (UTF-7)"
MapCodePageDataItem( 65001, 1200, "utf-8", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Unicode (UTF-8)"
-#else //FEATURE_CORECLR
-
-// Total Items: 146
-// code page, family code page, web name, header name, body name, flags
-
-
- MapCodePageDataItem( 37, 1252, "IBM037", 0), // "IBM EBCDIC (US-Canada)"
- MapCodePageDataItem( 437, 1252, "IBM437", 0), // "OEM United States"
- MapCodePageDataItem( 500, 1252, "IBM500", 0), // "IBM EBCDIC (International)"
- MapCodePageDataItem( 708, 1256, "ASMO-708", MIMECONTF_BROWSER | MIMECONTF_SAVABLE_BROWSER), // "Arabic (ASMO 708)"
- MapCodePageDataItem( 720, 1256, "DOS-720", MIMECONTF_BROWSER | MIMECONTF_SAVABLE_BROWSER), // "Arabic (DOS)"
- MapCodePageDataItem( 737, 1253, "ibm737", 0), // "Greek (DOS)"
- MapCodePageDataItem( 775, 1257, "ibm775", 0), // "Baltic (DOS)"
- MapCodePageDataItem( 850, 1252, "ibm850", 0), // "Western European (DOS)"
- MapCodePageDataItem( 852, 1250, "ibm852", MIMECONTF_BROWSER | MIMECONTF_SAVABLE_BROWSER), // "Central European (DOS)"
- MapCodePageDataItem( 855, 1252, "IBM855", 0), // "OEM Cyrillic"
- MapCodePageDataItem( 857, 1254, "ibm857", 0), // "Turkish (DOS)"
- MapCodePageDataItem( 858, 1252, "IBM00858", 0), // "OEM Multilingual Latin I"
- MapCodePageDataItem( 860, 1252, "IBM860", 0), // "Portuguese (DOS)"
- MapCodePageDataItem( 861, 1252, "ibm861", 0), // "Icelandic (DOS)"
- MapCodePageDataItem( 862, 1255, "DOS-862", MIMECONTF_BROWSER | MIMECONTF_SAVABLE_BROWSER), // "Hebrew (DOS)"
- MapCodePageDataItem( 863, 1252, "IBM863", 0), // "French Canadian (DOS)"
- MapCodePageDataItem( 864, 1256, "IBM864", 0), // "Arabic (864)"
- MapCodePageDataItem( 865, 1252, "IBM865", 0), // "Nordic (DOS)"
- MapCodePageDataItem( 866, 1251, "cp866", MIMECONTF_BROWSER | MIMECONTF_SAVABLE_BROWSER), // "Cyrillic (DOS)"
- MapCodePageDataItem( 869, 1253, "ibm869", 0), // "Greek, Modern (DOS)"
- MapCodePageDataItem( 870, 1250, "IBM870", 0), // "IBM EBCDIC (Multilingual Latin-2)"
- MapCodePageDataItem( 874, 874, "windows-874", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Thai (Windows)"
- MapCodePageDataItem( 875, 1253, "cp875", 0), // "IBM EBCDIC (Greek Modern)"
- MapCodePageDataItem( 932, 932, "|shift_jis|iso-2022-jp|iso-2022-jp", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Japanese (Shift-JIS)"
- MapCodePageDataItem( 936, 936, "gb2312", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Chinese Simplified (GB2312)"
- MapCodePageDataItem( 949, 949, "ks_c_5601-1987", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Korean"
- MapCodePageDataItem( 950, 950, "big5", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Chinese Traditional (Big5)"
- MapCodePageDataItem( 1026, 1254, "IBM1026", 0), // "IBM EBCDIC (Turkish Latin-5)"
- MapCodePageDataItem( 1047, 1252, "IBM01047", 0), // "IBM Latin-1"
- MapCodePageDataItem( 1140, 1252, "IBM01140", 0), // "IBM EBCDIC (US-Canada-Euro)"
- MapCodePageDataItem( 1141, 1252, "IBM01141", 0), // "IBM EBCDIC (Germany-Euro)"
- MapCodePageDataItem( 1142, 1252, "IBM01142", 0), // "IBM EBCDIC (Denmark-Norway-Euro)"
- MapCodePageDataItem( 1143, 1252, "IBM01143", 0), // "IBM EBCDIC (Finland-Sweden-Euro)"
- MapCodePageDataItem( 1144, 1252, "IBM01144", 0), // "IBM EBCDIC (Italy-Euro)"
- MapCodePageDataItem( 1145, 1252, "IBM01145", 0), // "IBM EBCDIC (Spain-Euro)"
- MapCodePageDataItem( 1146, 1252, "IBM01146", 0), // "IBM EBCDIC (UK-Euro)"
- MapCodePageDataItem( 1147, 1252, "IBM01147", 0), // "IBM EBCDIC (France-Euro)"
- MapCodePageDataItem( 1148, 1252, "IBM01148", 0), // "IBM EBCDIC (International-Euro)"
- MapCodePageDataItem( 1149, 1252, "IBM01149", 0), // "IBM EBCDIC (Icelandic-Euro)"
- MapCodePageDataItem( 1200, 1200, "utf-16", MIMECONTF_SAVABLE_BROWSER), // "Unicode"
- MapCodePageDataItem( 1201, 1200, "utf-16BE", 0), // Big Endian, old FFFE BOM seems backwards, think of the BOM in little endian order.
- MapCodePageDataItem( 1250, 1250, "|windows-1250|windows-1250|iso-8859-2", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Central European (Windows)"
- MapCodePageDataItem( 1251, 1251, "|windows-1251|windows-1251|koi8-r", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Cyrillic (Windows)"
- MapCodePageDataItem( 1252, 1252, "|Windows-1252|Windows-1252|iso-8859-1", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Western European (Windows)"
- MapCodePageDataItem( 1253, 1253, "|windows-1253|windows-1253|iso-8859-7", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Greek (Windows)"
- MapCodePageDataItem( 1254, 1254, "|windows-1254|windows-1254|iso-8859-9", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Turkish (Windows)"
- MapCodePageDataItem( 1255, 1255, "windows-1255", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Hebrew (Windows)"
- MapCodePageDataItem( 1256, 1256, "windows-1256", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Arabic (Windows)"
- MapCodePageDataItem( 1257, 1257, "windows-1257", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Baltic (Windows)"
- MapCodePageDataItem( 1258, 1258, "windows-1258", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Vietnamese (Windows)"
- MapCodePageDataItem( 1361, 949, "Johab", 0), // "Korean (Johab)"
- MapCodePageDataItem( 10000, 1252, "macintosh", 0), // "Western European (Mac)"
- MapCodePageDataItem( 10001, 932, "x-mac-japanese", 0), // "Japanese (Mac)"
- MapCodePageDataItem( 10002, 950, "x-mac-chinesetrad", 0), // "Chinese Traditional (Mac)"
- MapCodePageDataItem( 10003, 949, "x-mac-korean", 0), // "Korean (Mac)"
- MapCodePageDataItem( 10004, 1256, "x-mac-arabic", 0), // "Arabic (Mac)"
- MapCodePageDataItem( 10005, 1255, "x-mac-hebrew", 0), // "Hebrew (Mac)"
- MapCodePageDataItem( 10006, 1253, "x-mac-greek", 0), // "Greek (Mac)"
- MapCodePageDataItem( 10007, 1251, "x-mac-cyrillic", 0), // "Cyrillic (Mac)"
- MapCodePageDataItem( 10008, 936, "x-mac-chinesesimp", 0), // "Chinese Simplified (Mac)"
- MapCodePageDataItem( 10010, 1250, "x-mac-romanian", 0), // "Romanian (Mac)"
- MapCodePageDataItem( 10017, 1251, "x-mac-ukrainian", 0), // "Ukrainian (Mac)"
- MapCodePageDataItem( 10021, 874, "x-mac-thai", 0), // "Thai (Mac)"
- MapCodePageDataItem( 10029, 1250, "x-mac-ce", 0), // "Central European (Mac)"
- MapCodePageDataItem( 10079, 1252, "x-mac-icelandic", 0), // "Icelandic (Mac)"
- MapCodePageDataItem( 10081, 1254, "x-mac-turkish", 0), // "Turkish (Mac)"
- MapCodePageDataItem( 10082, 1250, "x-mac-croatian", 0), // "Croatian (Mac)"
- MapCodePageDataItem( 12000, 1200, "utf-32", 0), // "Unicode (UTF-32)"
- MapCodePageDataItem( 12001, 1200, "utf-32BE", 0), // "Unicode (UTF-32 Big Endian)"
- MapCodePageDataItem( 20000, 950, "x-Chinese-CNS", 0), // "Chinese Traditional (CNS)"
- MapCodePageDataItem( 20001, 950, "x-cp20001", 0), // "TCA Taiwan"
- MapCodePageDataItem( 20002, 950, "x-Chinese-Eten", 0), // "Chinese Traditional (Eten)"
- MapCodePageDataItem( 20003, 950, "x-cp20003", 0), // "IBM5550 Taiwan"
- MapCodePageDataItem( 20004, 950, "x-cp20004", 0), // "TeleText Taiwan"
- MapCodePageDataItem( 20005, 950, "x-cp20005", 0), // "Wang Taiwan"
- MapCodePageDataItem( 20105, 1252, "x-IA5", 0), // "Western European (IA5)"
- MapCodePageDataItem( 20106, 1252, "x-IA5-German", 0), // "German (IA5)"
- MapCodePageDataItem( 20107, 1252, "x-IA5-Swedish", 0), // "Swedish (IA5)"
- MapCodePageDataItem( 20108, 1252, "x-IA5-Norwegian", 0), // "Norwegian (IA5)"
- MapCodePageDataItem( 20127, 1252, "us-ascii", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS), // "US-ASCII"
- MapCodePageDataItem( 20261, 1252, "x-cp20261", 0), // "T.61"
- MapCodePageDataItem( 20269, 1252, "x-cp20269", 0), // "ISO-6937"
- MapCodePageDataItem( 20273, 1252, "IBM273", 0), // "IBM EBCDIC (Germany)"
- MapCodePageDataItem( 20277, 1252, "IBM277", 0), // "IBM EBCDIC (Denmark-Norway)"
- MapCodePageDataItem( 20278, 1252, "IBM278", 0), // "IBM EBCDIC (Finland-Sweden)"
- MapCodePageDataItem( 20280, 1252, "IBM280", 0), // "IBM EBCDIC (Italy)"
- MapCodePageDataItem( 20284, 1252, "IBM284", 0), // "IBM EBCDIC (Spain)"
- MapCodePageDataItem( 20285, 1252, "IBM285", 0), // "IBM EBCDIC (UK)"
- MapCodePageDataItem( 20290, 932, "IBM290", 0), // "IBM EBCDIC (Japanese katakana)"
- MapCodePageDataItem( 20297, 1252, "IBM297", 0), // "IBM EBCDIC (France)"
- MapCodePageDataItem( 20420, 1256, "IBM420", 0), // "IBM EBCDIC (Arabic)"
- MapCodePageDataItem( 20423, 1253, "IBM423", 0), // "IBM EBCDIC (Greek)"
- MapCodePageDataItem( 20424, 1255, "IBM424", 0), // "IBM EBCDIC (Hebrew)"
- MapCodePageDataItem( 20833, 949, "x-EBCDIC-KoreanExtended", 0), // "IBM EBCDIC (Korean Extended)"
- MapCodePageDataItem( 20838, 874, "IBM-Thai", 0), // "IBM EBCDIC (Thai)"
- MapCodePageDataItem( 20866, 1251, "koi8-r", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Cyrillic (KOI8-R)"
- MapCodePageDataItem( 20871, 1252, "IBM871", 0), // "IBM EBCDIC (Icelandic)"
- MapCodePageDataItem( 20880, 1251, "IBM880", 0), // "IBM EBCDIC (Cyrillic Russian)"
- MapCodePageDataItem( 20905, 1254, "IBM905", 0), // "IBM EBCDIC (Turkish)"
- MapCodePageDataItem( 20924, 1252, "IBM00924", 0), // "IBM Latin-1"
- MapCodePageDataItem( 20932, 932, "EUC-JP", 0), // "Japanese (JIS 0208-1990 and 0212-1990)"
- MapCodePageDataItem( 20936, 936, "x-cp20936", 0), // "Chinese Simplified (GB2312-80)"
- MapCodePageDataItem( 20949, 949, "x-cp20949", 0), // "Korean Wansung"
- MapCodePageDataItem( 21025, 1251, "cp1025", 0), // "IBM EBCDIC (Cyrillic Serbian-Bulgarian)"
- MapCodePageDataItem( 21866, 1251, "koi8-u", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Cyrillic (KOI8-U)"
- MapCodePageDataItem( 28591, 1252, "iso-8859-1", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Western European (ISO)"
- MapCodePageDataItem( 28592, 1250, "iso-8859-2", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Central European (ISO)"
- MapCodePageDataItem( 28593, 1254, "iso-8859-3", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS), // "Latin 3 (ISO)"
- MapCodePageDataItem( 28594, 1257, "iso-8859-4", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Baltic (ISO)"
- MapCodePageDataItem( 28595, 1251, "iso-8859-5", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Cyrillic (ISO)"
- MapCodePageDataItem( 28596, 1256, "iso-8859-6", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Arabic (ISO)"
- MapCodePageDataItem( 28597, 1253, "iso-8859-7", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Greek (ISO)"
- MapCodePageDataItem( 28598, 1255, "iso-8859-8", MIMECONTF_BROWSER | MIMECONTF_SAVABLE_BROWSER), // "Hebrew (ISO-Visual)"
- MapCodePageDataItem( 28599, 1254, "iso-8859-9", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Turkish (ISO)"
- MapCodePageDataItem( 28603, 1257, "iso-8859-13", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS), // "Estonian (ISO)"
- MapCodePageDataItem( 28605, 1252, "iso-8859-15", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Latin 9 (ISO)"
- MapCodePageDataItem( 29001, 1252, "x-Europa", 0), // "Europa"
- MapCodePageDataItem( 38598, 1255, "iso-8859-8-i", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Hebrew (ISO-Logical)"
- MapCodePageDataItem( 50220, 932, "iso-2022-jp", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS), // "Japanese (JIS)"
- MapCodePageDataItem( 50221, 932, "|csISO2022JP|iso-2022-jp|iso-2022-jp", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Japanese (JIS-Allow 1 byte Kana)"
- MapCodePageDataItem( 50222, 932, "iso-2022-jp", 0), // "Japanese (JIS-Allow 1 byte Kana - SO/SI)"
- MapCodePageDataItem( 50225, 949, "|iso-2022-kr|euc-kr|iso-2022-kr", MIMECONTF_MAILNEWS), // "Korean (ISO)"
- MapCodePageDataItem( 50227, 936, "x-cp50227", 0), // "Chinese Simplified (ISO-2022)"
-//MapCodePageDataItem( 50229, 950, L"x-cp50229", L"x-cp50229", L"x-cp50229", 0}, // "Chinese Traditional (ISO-2022)"
-//MapCodePageDataItem( 50930, 932, L"cp930", L"cp930", L"cp930", 0}, // "IBM EBCDIC (Japanese and Japanese Katakana)"
-//MapCodePageDataItem( 50931, 932, L"x-EBCDIC-JapaneseAndUSCanada", L"x-EBCDIC-JapaneseAndUSCanada", L"x-EBCDIC-JapaneseAndUSCanada", 0}, // "IBM EBCDIC (Japanese and US-Canada)"
-//MapCodePageDataItem( 50933, 949, L"cp933", L"cp933", L"cp933", 0}, // "IBM EBCDIC (Korean and Korean Extended)"
-//MapCodePageDataItem( 50935, 936, L"cp935", L"cp935", L"cp935", 0}, // "IBM EBCDIC (Simplified Chinese)"
-//MapCodePageDataItem( 50937, 950, L"cp937", L"cp937", L"cp937", 0}, // "IBM EBCDIC (Traditional Chinese)"
-//MapCodePageDataItem( 50939, 932, L"cp939", L"cp939", L"cp939", 0}, // "IBM EBCDIC (Japanese and Japanese-Latin)"
- MapCodePageDataItem( 51932, 932, "euc-jp", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Japanese (EUC)"
- MapCodePageDataItem( 51936, 936, "EUC-CN", 0), // "Chinese Simplified (EUC)"
- MapCodePageDataItem( 51949, 949, "euc-kr", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS), // "Korean (EUC)"
- MapCodePageDataItem( 52936, 936, "hz-gb-2312", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Chinese Simplified (HZ)"
- MapCodePageDataItem( 54936, 936, "GB18030", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Chinese Simplified (GB18030)"
- MapCodePageDataItem( 57002, 57002, "x-iscii-de", 0), // "ISCII Devanagari"
- MapCodePageDataItem( 57003, 57003, "x-iscii-be", 0), // "ISCII Bengali"
- MapCodePageDataItem( 57004, 57004, "x-iscii-ta", 0), // "ISCII Tamil"
- MapCodePageDataItem( 57005, 57005, "x-iscii-te", 0), // "ISCII Telugu"
- MapCodePageDataItem( 57006, 57006, "x-iscii-as", 0), // "ISCII Assamese"
- MapCodePageDataItem( 57007, 57007, "x-iscii-or", 0), // "ISCII Oriya"
- MapCodePageDataItem( 57008, 57008, "x-iscii-ka", 0), // "ISCII Kannada"
- MapCodePageDataItem( 57009, 57009, "x-iscii-ma", 0), // "ISCII Malayalam"
- MapCodePageDataItem( 57010, 57010, "x-iscii-gu", 0), // "ISCII Gujarati"
- MapCodePageDataItem( 57011, 57011, "x-iscii-pa", 0), // "ISCII Punjabi"
- MapCodePageDataItem( 65000, 1200, "utf-7", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS), // "Unicode (UTF-7)"
- MapCodePageDataItem( 65001, 1200, "utf-8", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Unicode (UTF-8)"
-#endif // FEATURE_CORECLR
// End of data.
MapCodePageDataItem( 0, 0, NULL, 0),
BOOL result = FALSE;
BEGIN_QCALL;
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
- if(!(curDomain->m_bUseOsSorting))
- {
- handle = EnsureValidSortHandle(handle, handleOrigin, localeName);
- result = SortVersioning::SortDllIsDefinedString((SortVersioning::PSORTHANDLE) handle, COMPARE_STRING, 0, string, length);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- result = (curDomain->m_pCustomSortLibrary->pIsNLSDefinedString)(COMPARE_STRING, 0, NULL, string, length);
- }
- else
-#endif
{
// Function should be COMPARE_STRING, dwFlags should be NULL, lpVersionInfo should be NULL for now
result = NewApis::IsNLSDefinedString(COMPARE_STRING, 0, NULL, string, length);
}
// Added but disabled from desktop in .NET 4.0, stayed disabled in .NET 4.5
-#ifdef FEATURE_CORECLR
FCIMPL0(Object*, COMNlsInfo::nativeGetResourceFallbackArray)
{
CONTRACTL
}
FCIMPLEND
-#endif // FEATURE_CORECLR
INT32 COMNlsInfo::CallGetUserDefaultUILanguage()
{
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
- if(!(curDomain->m_bUseOsSorting) && handleOrigin == (INT_PTR) SortVersioning::GetSortHandle && ((SortVersioning::PSORTHANDLE) handle)->dwNLSVersion == curDomain->m_sortVersion)
- {
- return handle;
- }
-
- if(curDomain->m_bUseOsSorting && curDomain->m_pCustomSortLibrary == NULL && handleOrigin == (INT_PTR) NewApis::LCMapStringEx)
- {
- return handle;
- }
-
- if(curDomain->m_bUseOsSorting && curDomain->m_pCustomSortLibrary != NULL && handleOrigin == (INT_PTR) curDomain->m_pCustomSortLibrary->pLCMapStringEx)
- {
- return handle;
- }
-
- // At this point, we can't reuse the sort handle (it has different sort semantics than this domain) so we need to get a new one.
- INT_PTR newHandleOrigin;
- return InitSortHandleHelper(localeName, &newHandleOrigin);
-#else
// For CoreCLR, on Windows 8 and up the handle will be valid. on downlevels the handle will be null
return handle;
-#endif
}
#ifdef FEATURE_SYNTHETIC_CULTURES
#endif // FEATURE_SYNTHETIC_CULTURES
-#ifndef FEATURE_CORECLR
-FCIMPL1(FC_BOOL_RET, COMNlsInfo::nativeSetThreadLocale, StringObject* localeNameUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(localeNameUNSAFE));
- } CONTRACTL_END;
-
- LCID lcid = 0;
-
- // TODO: NLS Arrowhead -A bit scary becausue Set ThreadLocale can't handle custom cultures?
- STRINGREF localeName = (STRINGREF)localeNameUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(localeName);
- lcid=NewApis::LocaleNameToLCID(localeName->GetBuffer(),0);
- if (lcid == 0)
- {
- ThrowHR(HRESULT_FROM_WIN32(GetLastError()));
- }
- HELPER_METHOD_FRAME_END();
-
-
- BOOL result = TRUE;
-
- // SetThreadLocale doesn't handle names/custom cultures
-#ifdef _MSC_VER
-// Get rid of the SetThreadLocale warning in OACR:
-#pragma warning(push)
-#pragma warning(disable:38010)
-#endif
- result = ::SetThreadLocale(lcid);
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
- FC_RETURN_BOOL(result);
-}
-FCIMPLEND
-#endif
FCIMPL2(Object*, COMNlsInfo::nativeGetLocaleInfoEx, StringObject* localeNameUNSAFE, INT32 lcType)
handle = EnsureValidSortHandle(handle, handleOrigin, localeName);
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
- if(!(curDomain->m_bUseOsSorting))
- {
- result = SortVersioning::SortDllCompareString((SortVersioning::PSORTHANDLE) handle, flags, &string1[offset1], length1, &string2[offset2], length2, NULL, 0);
- }
- else if (curDomain->m_pCustomSortLibrary != NULL) {
- result = (curDomain->m_pCustomSortLibrary->pCompareStringEx)(handle != NULL ? NULL : localeName, flags, &string1[offset1], length1, &string2[offset2], length2, NULL, NULL, (LPARAM) handle);
- }
- else
-#endif
{
result = NewApis::CompareStringEx(handle != NULL ? NULL : localeName, flags, &string1[offset1], length1, &string2[offset2], length2,NULL,NULL, (LPARAM) handle);
}
COMPlusThrowArgumentNull(W("string"),W("ArgumentNull_String"));
}
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-#endif // FEATURE_CORECLR
if(length > 0 && UseConstantSpaceHashAlgorithm()
// Note that we can't simply do the hash without the entropy and then try to add it after the fact we need the hash function itself to pass entropy to its inputs.
#ifdef FEATURE_RANDOMIZED_STRING_HASHING
&& !bForceRandomizedHashing
-#ifndef FEATURE_CORECLR
- && !curDomain->m_pNlsHashProvider->GetUseRandomHashing()
-#else
&& !COMNlsHashProvider::s_NlsHashProvider.GetUseRandomHashing()
-#endif // FEATURE_CORECLR
#endif // FEATURE_RANDOMIZED_STRING_HASHING
)
{
-#ifndef FEATURE_CORECLR
- if(!(curDomain->m_bUseOsSorting))
- {
- iReturnHash=SortVersioning::SortDllGetHashCode((SortVersioning::PSORTHANDLE) handle, dwFlagsIn, string, length, NULL, 0);
- }
- else
-#endif
{
int iRes = 0;
int iHashValue = 0;
-#ifndef FEATURE_CORECLR
- if (curDomain->m_pCustomSortLibrary != NULL)
- {
- iRes = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(localeName, dwFlagsIn | LCMAP_HASH, string, length, (LPWSTR) &iHashValue, sizeof(INT32), NULL, NULL, 0);
- }
- else
-#endif
{
iRes = NewApis::LCMapStringEx(localeName, dwFlagsIn | LCMAP_HASH, string, length, (LPWSTR) &iHashValue, sizeof(INT32), NULL, NULL, 0);
}
//
// Assert if we might hit an AV in LCMapStringEx for the invariant culture.
_ASSERTE(length > 0 || (dwFlags & LCMAP_LINGUISTIC_CASING) == 0);
-#ifndef FEATURE_CORECLR
- if(!(curDomain->m_bUseOsSorting))
- {
- byteCount=SortVersioning::SortDllGetSortKey((SortVersioning::PSORTHANDLE) handle, dwFlagsIn, string, length, NULL, 0, NULL, 0);
- }
- else if (curDomain->m_pCustomSortLibrary != NULL)
- {
- byteCount = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(handle != NULL ? NULL : localeName, dwFlags, string, length, NULL, 0, NULL, NULL, (LPARAM) handle);
- }
- else
-#endif
{
byteCount=NewApis::LCMapStringEx(handle != NULL ? NULL : localeName, dwFlags, string, length, NULL, 0, NULL, NULL, (LPARAM) handle);
}
CQuickBytesSpecifySize<MAX_STRING_VALUE * sizeof(WCHAR)> qbBuffer;
BYTE* pByte = (BYTE*)qbBuffer.AllocThrows(byteCount);
-#ifndef FEATURE_CORECLR
- if(!(curDomain->m_bUseOsSorting))
- {
- SortVersioning::SortDllGetSortKey((SortVersioning::PSORTHANDLE) handle, dwFlagsIn, string, length, pByte, byteCount, NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(handle != NULL ? NULL : localeName, dwFlags, string, length, (LPWSTR)pByte, byteCount, NULL, NULL, (LPARAM) handle);
- }
- else
-#endif
{
NewApis::LCMapStringEx(handle != NULL ? NULL : localeName, dwFlags, string, length, (LPWSTR)pByte, byteCount, NULL,NULL, (LPARAM) handle);
}
-#ifndef FEATURE_CORECLR
- iReturnHash = curDomain->m_pNlsHashProvider->HashSortKey(pByte, byteCount, bForceRandomizedHashing, additionalEntropy);
-#else
iReturnHash = COMNlsHashProvider::s_NlsHashProvider.HashSortKey(pByte, byteCount, bForceRandomizedHashing, additionalEntropy);
-#endif // FEATURE_CORECLR
}
}
END_QCALL;
handle = EnsureValidSortHandle(handle, handleOrigin, localeName->GetBuffer());
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
- //For a versioned sort, Invariant should still use the OS
- if(!(curDomain->m_bUseOsSorting) && !isInvariantLocale)
- {
- ret_LCMapStringEx = SortVersioning::SortDllChangeCase((SortVersioning::PSORTHANDLE) handle,
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing:
- LCMAP_LOWERCASE | linguisticCasing,
- &wch,
- 1,
- &retVal,
- 1,
- NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- ret_LCMapStringEx = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(handle != NULL ? NULL : localeName->GetBuffer(),
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing:
- LCMAP_LOWERCASE | linguisticCasing,
- &wch,
- 1,
- &retVal,
- 1,
- NULL,
- NULL,
- (LPARAM) handle);
- }
- else
-#endif
{
ret_LCMapStringEx = NewApis::LCMapStringEx(handle != NULL ? NULL : localeName->GetBuffer(),
bIsToUpper?LCMAP_UPPERCASE | linguisticCasing:
LPWSTR pResultStr = gc.pResult->GetBuffer();
int result;
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
- //Invariant should always use OS
- if(!(curDomain->m_bUseOsSorting) && !isInvariantLocale)
- {
- result = SortVersioning::SortDllChangeCase((SortVersioning::PSORTHANDLE) handle,
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing:
- LCMAP_LOWERCASE | linguisticCasing,
- gc.pString->GetBuffer(),
- nLengthInput,
- pResultStr,
- nLengthOutput,
- NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- result = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(handle != NULL ? NULL : (gc.pLocale)->GetBuffer(),
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing :
- LCMAP_LOWERCASE | linguisticCasing,
- gc.pString->GetBuffer(),
- nLengthInput,
- pResultStr,
- nLengthOutput,
- NULL,
- NULL,
- (LPARAM) handle);
- }
- else
-#endif
{
result = NewApis::LCMapStringEx(handle != NULL ? NULL : (gc.pLocale)->GetBuffer(),
bIsToUpper?LCMAP_UPPERCASE | linguisticCasing :
ThrowLastError();
}
// need to update buffer
-#ifndef FEATURE_CORECLR
- //Invariant should always use OS
- if(!(curDomain->m_bUseOsSorting) && !IsInvariantLocale(gc.pLocale))
- {
- nLengthOutput = SortVersioning::SortDllChangeCase((SortVersioning::PSORTHANDLE) handle,
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing:
- LCMAP_LOWERCASE | linguisticCasing,
- gc.pString->GetBuffer(),
- nLengthInput,
- NULL,
- 0,
- NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- nLengthOutput = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(handle != NULL ? NULL : (gc.pLocale)->GetBuffer(),
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing :
- LCMAP_LOWERCASE | linguisticCasing,
- gc.pString->GetBuffer(),
- nLengthInput,
- NULL,
- 0,
- NULL,
- NULL,
- (LPARAM) handle);
- }
- else
-#endif
{
nLengthOutput = NewApis::LCMapStringEx(handle != NULL ? NULL : (gc.pLocale)->GetBuffer(),
bIsToUpper?LCMAP_UPPERCASE | linguisticCasing :
gc.pResult = StringObject::NewString(nLengthOutput);
pResultStr = gc.pResult->GetBuffer();
-#ifndef FEATURE_CORECLR
- //Invariant should always use OS
- if(!(curDomain->m_bUseOsSorting) && !IsInvariantLocale(gc.pLocale))
- {
- result = SortVersioning::SortDllChangeCase((SortVersioning::PSORTHANDLE) handle,
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing:
- LCMAP_LOWERCASE | linguisticCasing,
- gc.pString->GetBuffer(),
- nLengthInput,
- pResultStr,
- nLengthOutput,
- NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- result = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(handle != NULL ? NULL : (gc.pLocale)->GetBuffer(),
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing :
- LCMAP_LOWERCASE | linguisticCasing,
- gc.pString->GetBuffer(),
- nLengthInput,
- pResultStr,
- nLengthOutput,
- NULL,
- NULL,
- (LPARAM) handle);
- }
- else
-#endif
{
result = NewApis::LCMapStringEx(handle != NULL ? NULL : (gc.pLocale)->GetBuffer(),
bIsToUpper?LCMAP_UPPERCASE | linguisticCasing :
*((LPVOID *)&strA)=pvStrA;
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-#endif
//
// If we know that we don't have any high characters (the common case) we can
{
// Notice that for Turkish and Azeri we don't get here and shouldn't use this
// fast path because of their special Latin casing rules.
-#ifndef FEATURE_CORECLR
- result = curDomain->m_pNlsHashProvider->HashiStringKnownLower80(strA->GetBuffer(), strA->GetStringLength(), bForceRandomizedHashing, additionalEntropy);
-#else
result = COMNlsHashProvider::s_NlsHashProvider.HashiStringKnownLower80(strA->GetBuffer(), strA->GetStringLength(), bForceRandomizedHashing, additionalEntropy);
-#endif // FEATURE_CORECLR
}
else
{
}
int lcmapResult;
-#ifndef FEATURE_CORECLR
- if(!(curDomain->m_bUseOsSorting))
- {
- lcmapResult = SortVersioning::SortDllChangeCase((SortVersioning::PSORTHANDLE) handle,
- LCMAP_UPPERCASE | linguisticCasing,
- strA->GetBuffer(),
- length,
- pNewStr,
- length,
- NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- lcmapResult = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(handle != NULL ? NULL : localeName->GetBuffer(),
- LCMAP_UPPERCASE | linguisticCasing,
- strA->GetBuffer(),
- length,
- pNewStr,
- length,
- NULL, NULL, (LPARAM) handle);
- }
- else
-#endif
{
lcmapResult = NewApis::LCMapStringEx(handle != NULL ? NULL : localeName->GetBuffer(),
LCMAP_UPPERCASE | linguisticCasing,
// Get hash for the upper case of the new string
-#ifndef FEATURE_CORECLR
- result = curDomain->m_pNlsHashProvider->HashString(pNewStr, length, (BOOL)bForceRandomizedHashing, additionalEntropy);
-#else
result = COMNlsHashProvider::s_NlsHashProvider.HashString(pNewStr, length, (BOOL)bForceRandomizedHashing, additionalEntropy);
-#endif // FEATURE_CORECLR
}
END_SO_INTOLERANT_CODE
else {
lpSearchStart = &lpStringSource[sourceIndex];
}
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
- // Check if the default sorting is overridden
- if (curDomain->m_pCustomSortLibrary != NULL)
- {
- *foundIndex = (curDomain->m_pCustomSortLibrary->pFindStringOrdinal)(
- dwFindNLSStringFlags,
- lpSearchStart,
- cchSource,
- lpStringValue,
- cchValue,
- TRUE);
- result = TRUE;
- }
- else
-#endif
{
#ifndef FEATURE_CORESYSTEM
// kernel function pointer
_ASSERT(length2 >= 0);
// Do the comparison
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
- if (curDomain->m_pCustomSortLibrary != NULL) {
- result = (curDomain->m_pCustomSortLibrary->pCompareStringOrdinal)(string1 + index1, length1, string2 + index2, length2, TRUE);
- }
- else
-#endif
{
result = NewApis::CompareStringOrdinal(string1 + index1, length1, string2 + index2, length2, TRUE);
}
if (!hNormalization)
ThrowLastError();
}
-#ifndef FEATURE_CORECLR
- // in coreclr we should always find the normalization in kernel32 as it supports Win7 and up
- else
- {
- HRESULT hr = g_pCLRRuntime->LoadLibrary(NORMALIZATION_DLL, &hNormalization);
- if (FAILED(hr))
- ThrowHR(hr);
- }
-#endif // FEATURE_CORECLR
_ASSERTE(hNormalization != NULL);
m_hNormalization = hNormalization;
gc.stringResult = StringObject::NewString(buffer, result - 1);
SetObjectReference((OBJECTREF*)&(gc.cultureData->sSpecificCulture), gc.stringResult, NULL);
-#ifdef FEATURE_CORECLR
if (!IsWindows7())
{
// For neutrals on Windows 7 + the neutral windows name can be the same as the neutral name,
gc.stringResult = StringObject::NewString(buffer, result - 1);
SetObjectReference((OBJECTREF*)&(gc.cultureData->sWindowsName), gc.stringResult, NULL);
}
-#endif
}
SetObjectReference((OBJECTREF*)&(gc.cultureData->sName), gc.stringResult, NULL);
}
-#ifdef FEATURE_CORECLR
// For Silverlight make sure that the sorting tables are available (< Vista may not have east asian installed)
result = NewApis::CompareStringEx(((STRINGREF)gc.cultureData->sWindowsName)->GetBuffer(),
0, W("A"), 1, W("B"), 1, NULL, NULL, 0);
if (result == 0) goto Exit;
-#endif
// It succeeded.
success = TRUE;
BEGIN_QCALL;
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
- handle = EnsureValidSortHandle(handle, handleOrigin, lpLocaleName);
-#endif
#define RESERVED_FIND_ASCII_STRING 0x20000000 // This flag used only to tell the sorting DLL can assume the string characters are in ASCII.
-#ifndef FEATURE_CORECLR
- int asciiFlag = (dwFindNLSStringFlags & RESERVED_FIND_ASCII_STRING);
-#endif // FEATURE_CORECLR
dwFindNLSStringFlags &= ~RESERVED_FIND_ASCII_STRING;
{
if (dwFindNLSStringFlags & (FIND_FROMEND | FIND_ENDSWITH))
{
-#ifndef FEATURE_CORECLR
- if(!(curDomain->m_bUseOsSorting))
- {
- retValue = SortVersioning::SortDllFindString((SortVersioning::PSORTHANDLE) handle,
- dwFindNLSStringFlags | asciiFlag,
- &lpStringSource[sourceIndex - cchSource + 1],
- cchSource,
- lpStringValue,
- cchValue,
- NULL, NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- retValue = (curDomain->m_pCustomSortLibrary->pFindNLSStringEx)(
- handle != NULL ? NULL : lpLocaleName,
- dwFindNLSStringFlags,
- &lpStringSource[sourceIndex - cchSource + 1],
- cchSource,
- lpStringValue,
- cchValue, NULL, NULL, NULL, (LPARAM) handle);
- }
- else
-#endif
{
retValue = NewApis::FindNLSStringEx(
handle != NULL ? NULL : lpLocaleName,
}
else
{
-#ifndef FEATURE_CORECLR
- if(!(curDomain->m_bUseOsSorting))
- {
- retValue = SortVersioning::SortDllFindString((SortVersioning::PSORTHANDLE) handle,
- dwFindNLSStringFlags | asciiFlag,
- &lpStringSource[sourceIndex],
- cchSource,
- lpStringValue,
- cchValue,
- NULL, NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- retValue = (curDomain->m_pCustomSortLibrary->pFindNLSStringEx)(
- handle != NULL ? NULL : lpLocaleName,
- dwFindNLSStringFlags,
- &lpStringSource[sourceIndex],
- cchSource,
- lpStringValue,
- cchValue, NULL, NULL, NULL, (LPARAM) handle);
- }
- else
-#endif
{
retValue = NewApis::FindNLSStringEx(
handle != NULL ? NULL : lpLocaleName,
BEGIN_QCALL;
-#ifndef FEATURE_CORECLR
- handle = EnsureValidSortHandle(handle, handleOrigin, pLocaleName);
-
- AppDomain* curDomain = GetAppDomain();
-
- if(!(curDomain->m_bUseOsSorting))
- {
- retValue = SortVersioning::SortDllGetSortKey((SortVersioning::PSORTHANDLE) handle,
- flags,
- pStringSource,
- cchSource,
- pTarget,
- cchTarget,
- NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- retValue = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(handle != NULL ? NULL : pLocaleName,
- flags | LCMAP_SORTKEY,
- pStringSource,
- cchSource,
- (LPWSTR)pTarget,
- cchTarget,
- NULL,
- NULL,
- (LPARAM) handle);
- }
- else
-#endif
{
// Just call NewApis::LCMapStringEx to do our work
retValue = NewApis::LCMapStringEx(handle != NULL ? NULL : pLocaleName,
INT_PTR pSort = NULL;
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
-#if _DEBUG
- _ASSERTE(curDomain->m_bSortingInitialized);
-#endif
-
- if(curDomain->m_bUseOsSorting)
- {
- pSort = InternalInitOsSortHandle(localeName, handleOrigin);
- }
- else
- {
- pSort = InternalInitVersionedSortHandle(localeName, handleOrigin);
- }
-#else
// coreclr will try to initialize the handle and if running on downlevel it'll just return null
pSort = InternalInitOsSortHandle(localeName, handleOrigin);
-#endif // FEATURE_CORECLR
return pSort;
}
-#ifndef FEATURE_CORECLR
-INT_PTR COMNlsInfo::InternalInitVersionedSortHandle(LPCWSTR localeName, __out INT_PTR* handleOrigin)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- CANNOT_TAKE_LOCK;
- PRECONDITION(localeName != NULL);
- } CONTRACTL_END;
-
- AppDomain* curDomain = GetAppDomain();
-
- if(curDomain->m_pCustomSortLibrary != NULL)
- {
- return NULL;
- }
-
- return InternalInitVersionedSortHandle(localeName, handleOrigin, curDomain->m_sortVersion);
-}
-
-INT_PTR COMNlsInfo::InternalInitVersionedSortHandle(LPCWSTR localeName, __out INT_PTR* handleOrigin, DWORD sortVersion)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- CANNOT_TAKE_LOCK;
- PRECONDITION(localeName != NULL);
- } CONTRACTL_END;
-
- INT_PTR pSort = NULL;
-
- _ASSERTE(NewApis::NotLeakingFrameworkOnlyCultures(localeName));
-
- *handleOrigin = (INT_PTR) SortVersioning::GetSortHandle;
-
- // try the requested version
- if(sortVersion != DEFAULT_SORT_VERSION)
- {
- NLSVERSIONINFO sortVersionInfo;
- sortVersionInfo.dwNLSVersionInfoSize = sizeof(NLSVERSIONINFO);
- sortVersionInfo.dwNLSVersion = sortVersion;
- sortVersionInfo.dwDefinedVersion = sortVersion;
- pSort = (INT_PTR) SortVersioning::GetSortHandle(localeName, &sortVersionInfo);
- }
-
- // fallback to default version
- if(pSort == NULL)
- {
- pSort = (INT_PTR) SortVersioning::GetSortHandle(localeName, NULL);
- }
-
- _ASSERTE(RunningOnWin8() || pSort != NULL);
-
- return pSort;
-}
-#endif //FEATURE_CORECLR
// Can return NULL
INT_PTR COMNlsInfo::InternalInitOsSortHandle(LPCWSTR localeName, __out INT_PTR* handleOrigin)
AppDomain* curDomain = GetAppDomain();
-#ifndef FEATURE_CORECLR
- if (RunningOnWin8() || curDomain->m_pCustomSortLibrary != NULL)
-#else
if (RunningOnWin8())
-#endif //FEATURE_CORECLR
{
LPARAM lSortHandle;
int ret;
-#ifndef FEATURE_CORECLR
- if (curDomain->m_pCustomSortLibrary != NULL)
- {
- ret = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(localeName, LCMAP_SORTHANDLE, NULL, 0, (LPWSTR) &lSortHandle, sizeof(LPARAM), NULL, NULL, 0);
- *handleOrigin = (INT_PTR) curDomain->m_pCustomSortLibrary->pLCMapStringEx;
- }
- else
-#endif //FEATURE_CORECLR
{
ret = NewApis::LCMapStringEx(localeName, LCMAP_SORTHANDLE, NULL, 0, (LPWSTR) &lSortHandle, sizeof(LPARAM), NULL, NULL, 0);
*handleOrigin = (INT_PTR) NewApis::LCMapStringEx;
BOOL ret = FALSE;
BEGIN_QCALL;
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
- if(curDomain->m_bUseOsSorting)
- {
- if(curDomain->m_pCustomSortLibrary != NULL)
- {
- ret = (curDomain->m_pCustomSortLibrary->pGetNLSVersionEx)(COMPARE_STRING, lpLocaleName, lpVersionInformation);
- }
- else
- {
- ret = GetNLSVersionEx(COMPARE_STRING, lpLocaleName, lpVersionInformation);
- }
- }
- else
- {
- handle = EnsureValidSortHandle(handle, handleOrigin, lpLocaleName);
-
- NLSVERSIONINFO nlsVersion;
- nlsVersion.dwNLSVersionInfoSize = sizeof(NLSVERSIONINFO);
-
- ret = SortVersioning::SortGetNLSVersion((SortVersioning::PSORTHANDLE) handle, COMPARE_STRING, &nlsVersion);
-
- lpVersionInformation->dwNLSVersion = nlsVersion.dwNLSVersion;
- lpVersionInformation->dwDefinedVersion = nlsVersion.dwDefinedVersion;
- lpVersionInformation->dwEffectiveId = 0;
- ZeroMemory(&(lpVersionInformation->guidCustomVersion), sizeof(GUID));
- }
-#else
ret = GetNLSVersionEx(COMPARE_STRING, lpLocaleName, lpVersionInformation);
-#endif // FEATURE_CORECLR
END_QCALL;
return ret;
}
-#ifndef FEATURE_CORECLR
-DWORD QCALLTYPE COMNlsInfo::InternalGetSortVersion()
-{
- CONTRACTL {
- QCALL_CHECK;
- } CONTRACTL_END;
-
- DWORD version = DEFAULT_SORT_VERSION;
-
- BEGIN_QCALL;
-
- AppDomain* curDomain = GetAppDomain();
- version = curDomain->m_sortVersion;
-
- END_QCALL;
-
- return version;
-}
-
-#endif //FEATURE_CORECLR
#include "stackwalk.h"
#include "dacdbiimpl.h"
-#ifndef FEATURE_CORECLR
-#include "assemblyusagelogmanager.h"
-#endif
#ifdef FEATURE_COMINTEROP
#include "runtimecallablewrapper.h"
HRESULT DacDbiInterfaceImpl::EnableNGENPolicy(CorDebugNGENPolicy ePolicy)
{
-#ifndef FEATURE_CORECLR
- DD_ENTER_MAY_THROW;
-
- // translate from our publicly exposed enum to the appropriate internal value
- AssemblyUsageLogManager::ASSEMBLY_USAGE_LOG_FLAGS asmFlag = AssemblyUsageLogManager::ASSEMBLY_USAGE_LOG_FLAGS_NONE;
-
- switch (ePolicy)
- {
- case DISABLE_LOCAL_NIC:
- asmFlag = AssemblyUsageLogManager::ASSEMBLY_USAGE_LOG_FLAGS_APPLOCALNGENDISABLED;
- break;
- default:
- return E_INVALIDARG;
- }
-
- // we should have made some selection
- _ASSERTE(asmFlag != AssemblyUsageLogManager::ASSEMBLY_USAGE_LOG_FLAGS_NONE);
-
- return AssemblyUsageLogManager::SetUsageLogFlag(asmFlag, TRUE);
-#else
return E_NOTIMPL;
-#endif // FEATURE_CORECLR
}
HRESULT DacDbiInterfaceImpl::SetNGENCompilerFlags(DWORD dwFlags)
CORCOMPILE_ASSEMBLY_SIGNATURE, COR_INFO );
}
-#ifndef FEATURE_CORECLR
-
-const NativeImageDumper::EnumMnemonics s_CorCompileDependencyInfoFlags[] =
-{
-#define CMDI_ENTRY(f) NativeImageDumper::EnumMnemonics(CORCOMPILE_DEPENDENCY_ ## f, W(#f))
-
-#ifdef FEATURE_APTCA
- CMDI_ENTRY(IS_APTCA),
- CMDI_ENTRY(IS_CAPTCA),
-#endif //FEATURE_APTCA
-#undef CMDI_ENTRY
-};
-
-#endif //!FEATURE_CORECLR
//error code return?
void
WriteFieldMDTokenImport( dwAssemblyDef, deps[i].dwAssemblyDef,
CORCOMPILE_DEPENDENCY, COR_INFO,
m_manifestImport );
-#ifndef FEATURE_CORECLR
- DisplayWriteFieldEnumerated( dependencyInfo, deps[i].dependencyInfo,
- CORCOMPILE_DEPENDENCY,
- s_CorCompileDependencyInfoFlags, W(", "),
- COR_INFO );
-#endif // !FEATURE_CORECLR
DisplayStartStructureWithOffset( signAssemblyDef,
DPtrToPreferredAddr(deps + i) + offsetof(CORCOMPILE_DEPENDENCY, signAssemblyDef),
sizeof(deps[i]).signAssemblyDef,
{
#define MSD_ENTRY(f) NativeImageDumper::EnumMnemonics(ModuleSecurityDescriptorFlags_ ## f, W(#f))
MSD_ENTRY(IsComputed),
-#ifdef FEATURE_APTCA
- MSD_ENTRY(IsAPTCA),
-#endif // FEATURE_APTCA
MSD_ENTRY(IsAllCritical),
MSD_ENTRY(IsAllTransparent),
MSD_ENTRY(IsTreatAsSafe),
return Cordb::CreateObject((CorDebugInterfaceVersion)iDebuggerVersion, IID_ICorDebug, (void **) ppCordb);
}
-#if defined(FEATURE_CORECLR)
//
// Public API.
// Telesto Creation path - only way to debug multi-instance.
return hr;
}
-#endif // FEATURE_CORECLR
HRESULT CordbProcess::EnableNGENPolicy(CorDebugNGENPolicy ePolicy)
{
-#ifdef FEATURE_CORECLR
return E_NOTIMPL;
-#else
- HRESULT hr = S_OK;
- PUBLIC_API_BEGIN(this);
-
- IDacDbiInterface* pDAC = GetProcess()->GetDAC();
- hr = pDAC->EnableNGENPolicy(ePolicy);
-
- PUBLIC_API_END(hr);
- return hr;
-#endif
}
// For Telesto, Dbi and Wks have a more flexible versioning allowed, as described by the Debugger
// Version Protocol String in DEBUGGER_PROTOCOL_STRING in DbgIpcEvents.h. This allows different build
// numbers, but the other protocol numbers should still match.
-#if !defined(FEATURE_CORECLR)
- bool fSkipVerCheck = false;
-#if _DEBUG
- // In debug builds, allow us to disable the version check to help with applying hotfixes.
- // The hotfix may be built against a compatible IPC protocol, but have a slightly different build number.
- fSkipVerCheck = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgSkipVerCheck) != 0;
-#endif
-
- if (!fSkipVerCheck)
- {
- //
- // These asserts double check that the version of the Right Side matches the version of the left side.
- //
- // If you hit these asserts, it is probably because you rebuilt mscordbi without rebuilding mscorwks, or rebuilt
- // mscorwks without rebuilding mscordbi. You might be able to ignore these asserts, but proceed at your own risk.
- //
- CONSISTENCY_CHECK_MSGF(VER_PRODUCTBUILD == GetDCB()->m_verMajor,
- ("version of %s (%d) in the debuggee does not match version of mscordbi.dll (%d) in the debugger.\n"
- "This means your setup is wrong. You can ignore this but proceed at your own risk.\n",
- MAIN_CLR_DLL_NAME_A, GetDCB()->m_verMajor, VER_PRODUCTBUILD));
- CONSISTENCY_CHECK_MSGF(VER_PRODUCTBUILD_QFE == GetDCB()->m_verMinor,
- ("QFE version of %s (%d) in the debuggee does not match QFE version of mscordbi.dll (%d) in the debugger.\n"
- "Both dlls have build # (%d).\n"
- "This means your setup is wrong. You can ignore this but proceed at your own risk.\n",
- MAIN_CLR_DLL_NAME_A, GetDCB()->m_verMinor, VER_PRODUCTBUILD_QFE, VER_PRODUCTBUILD));
- }
-#endif // !FEATURE_CORECLR
// These assertions verify that the debug manager is behaving correctly.
// An assertion failure here means that the runtime version of the debuggee is different from the runtime version of
// honored for SLv4.
if (requiredVersion <= 0)
{
-#if defined(FEATURE_CORECLR)
requiredVersion = 2;
-#else
- requiredVersion = 4;
-#endif
}
// Compare the version we were created for against the minimum required
event);
}
-#ifdef FEATURE_CORECLR
HRESULT Cordb::SetTargetCLR(HMODULE hmodTargetCLR)
{
if (m_initialized)
return S_OK;
}
-#endif // FEATURE_CORECLR
//-----------------------------------------------------------
// ICorDebug
// It is currently supported on Mac CoreCLR, but that may change.
bool Cordb::IsCreateProcessSupported()
{
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_DBGIPC_TRANSPORT_DI)
+#if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
return false;
#else
return true;
HRESULT hr = S_OK;
PUBLIC_API_BEGIN(this)
{
-#if defined(FEATURE_CORECLR)
hr = E_NOTIMPL;
-#else // !FEATURE_CORECLR
- hr = CopyOutString(m_szName, cchName, pcchName, szName);
-#endif // FEATURE_CORECLR
}
PUBLIC_API_END(hr);
return hr;
HRESULT hr = S_OK;
PUBLIC_API_BEGIN(this)
{
-#if defined(FEATURE_CORECLR)
hr = E_NOTIMPL;
-#else // !FEATURE_CORECLR
- hr = CopyOutString(m_szDescription, cchName, pcchName, szName);
-#endif // FEATURE_CORECLR
}
PUBLIC_API_END(hr);
return hr;
HRESULT hr = S_OK;
PUBLIC_API_BEGIN(this)
{
-#if defined(FEATURE_CORECLR)
hr = E_NOTIMPL;
-#else // !FEATURE_CORECLR
- hr = CopyOutString(m_szXml, cchName, pcchName, szName);
-#endif // FEATURE_CORECLR
}
PUBLIC_API_END(hr);
return hr;
HRESULT hr = S_OK;
PUBLIC_API_BEGIN(this)
{
-#if defined(FEATURE_CORECLR)
hr = E_NOTIMPL;
-#else // !FEATURE_CORECLR
- ValidateOrThrow(pFlags);
- *pFlags = this->m_flags;
-#endif // FEATURE_CORECLR
}
PUBLIC_API_END(hr);
return hr;
HRESULT hr = S_OK;
PUBLIC_API_BEGIN(this)
{
-#if defined(FEATURE_CORECLR)
hr = E_NOTIMPL;
-#else // !FEATURE_CORECLR
- ValidateOrThrow(pOsTid);
-
- *pOsTid = this->m_dwOSTID;
-#endif // FEATURE_CORECLR
}
PUBLIC_API_END(hr);
return hr;
// ICorDebug
//-----------------------------------------------------------
-#ifdef FEATURE_CORECLR
HRESULT SetTargetCLR(HMODULE hmodTargetCLR);
-#endif // FEATURE_CORECLR
COM_METHOD Initialize();
COM_METHOD Terminate();
extern DWORD gAppDomainTLSIndex;
#ifdef FEATURE_APPX
-#if defined(FEATURE_CORECLR)
extern BOOL g_fAppX;
-#else
-extern PTR_AppXRTInfo g_pAppXRTInfo;
-#endif
#endif // FEATURE_APPX
DacGlobals g_dacTable;
#include "datatest.h"
#endif // TEST_DATA_CONSISTENCY
-#if defined(FEATURE_CORECLR)
#include "dbgenginemetrics.h"
-#endif // FEATURE_CORECLR
#include "../../vm/rejit.h"
pDbgLockHolder->Acquire();
}
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#if !defined(FEATURE_PAL)
HANDLE g_hContinueStartupEvent = INVALID_HANDLE_VALUE;
_ASSERTE(g_pEEInterface != NULL);
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#if !defined(FEATURE_PAL)
if (IsWatsonEnabled() || IsTelestoDebugPackInstalled())
{
// Iff the debug pack is installed, then go through the telesto debugging pipeline.
#include <stdio.h>
#include <windows.h>
-#if !defined(FEATURE_CORECLR)
-#undef GetCurrentTime // works around a macro def conflict of GetCurrentTime
-#include <windows.ui.xaml.h>
-#endif // !FEATURE_CORECLR
#include <switches.h>
#include <winwrap.h>
OpenVirtualProcess private
OpenVirtualProcess2
-#ifdef FEATURE_CORECLR
CoreCLRCreateCordbObject private
-#endif // FEATURE_CORECLR
#if defined(FEATURE_DBGIPC_TRANSPORT_DI)
DllGetClassObject private
; Common exports
;
-#ifdef FEATURE_CORECLR
GetCLRRuntimeHost
GetMetaDataInternalInterfaceFromPublic
GetMetaDataPublicInterfaceFromInternal
-#else //FEATURE_CORECLR
-
-; VM
- DllGetClassObjectInternal private
- DllGetActivationFactoryImpl private
- GetClassActivatorForApplicationImpl private
- MetaDataGetDispenser
- GetMetaDataInternalInterface
- GetMetaDataInternalInterfaceFromPublic
- GetMetaDataPublicInterfaceFromInternal
- _CorExeMain2
- _CorDllMain
- CoInitializeEE
- CoUninitializeEE
- CoInitializeCor
- CoUninitializeCor
- PostErrorVA
-
- LoadStringRC @22
- ReOpenMetaDataWithMemory @23
-
- LoadStringRCEx
- ReOpenMetaDataWithMemoryEx private
- TranslateSecurityAttributes private
- GetPermissionRequests
- CorExitProcess
-#ifdef FEATURE_CLICKONCE
- CorLaunchApplication
-#endif
-
- CorMarkThreadInThreadPool
-
- LogHelp_LogAssert private
- LogHelp_NoGuiOnAssert private
- LogHelp_TerminateOnAssert private
-
- GetPrivateContextsPerfCounters private
-
- GetAssemblyMDImport private
-
- IEE private
-
-#ifdef FEATURE_FUSION
-; Fusion
- GetCachePath
- CreateAssemblyNameObject
- CreateApplicationContext
- CreateAssemblyCache
- CreateAssemblyEnum
- CreateHistoryReader
- LookupHistoryAssembly
- GetHistoryFileDirectory
- PreBindAssembly
- PreBindAssemblyEx
- SetMSIHandleForLogging
- NukeDownloadedCache
- ClearDownloadCache
- GetCLRIdentityManager
- CreateAssemblyConfigCookie
- DestroyAssemblyConfigCookie
- CompareAssemblyIdentity
- CompareAssemblyIdentityWithConfig
- InitializeFusion private
- CopyPDBs private
- DeleteShadowCache private
-#endif
-; Strong Name
- StrongNameErrorInfo
- StrongNameFreeBuffer
- StrongNameKeyGen
- StrongNameKeyGenEx
- StrongNameKeyInstall
- StrongNameKeyDelete
- StrongNameGetPublicKey
- StrongNameSignatureGeneration
- StrongNameSignatureGenerationEx
- StrongNameTokenFromAssembly
- StrongNameTokenFromAssemblyEx
- StrongNameTokenFromPublicKey
- StrongNameSignatureVerification
- StrongNameCompareAssemblies
- StrongNameHashSize
- StrongNameSignatureSize
- StrongNameSignatureVerificationEx
- GetHashFromAssemblyFile
- GetHashFromAssemblyFileW
- GetHashFromBlob
- GetHashFromFile
- GetHashFromFileW
- GetHashFromHandle
- StrongNameSignatureVerificationFromImage
- StrongNameGetBlob
- StrongNameGetBlobFromImage
- StrongNameSignatureVerificationEx2
- StrongNameGetPublicKeyEx
- StrongNameDigestGenerate
- StrongNameDigestSign
- StrongNameDigestEmbed
-
-; VM
-#ifdef FEATURE_COMINTEROP
- DllCanUnloadNowInternal private
-#endif
-#ifdef FEATURE_COMINTEROP_REGISTRATION
- ClrCreateManagedInstance
- DllRegisterServerInternal private
- DllUnregisterServerInternal private
- EEDllRegisterServer private
- EEDllUnregisterServer private
-#endif
- SetRuntimeInfo
- _CorExeMain
-#ifdef FEATURE_MIXEDMODE
- CorDllMainForThunk private
-#endif
- CoEEShutDownCOM
-#ifdef FEATURE_PREJIT
- NGenCreateNGenWorker
- LegacyNGenCreateZapper
- LegacyNGenFreeZapper
- LegacyNGenTryEnumerateFusionCache
- LegacyNGenCompile
-#endif
- GetAddrOfContractShutoffFlag private
- GetCLRFunction private
-
-#ifdef PROFILING_SUPPORTED
- AttachProfiler private
-#endif // PROFILING_SUPPORTED
-
-#ifdef FEATURE_FUSION
-; Fusion
- CreateInstallReferenceEnum
- InstallCustomModule
- GetAssemblyIdentityFromFile
- GetIdentityAuthority private
- ParseManifest private
- CreateCMSFromXml private
- GetAppIdAuthority private
- GetUserStore private
- CreateActContext private
- GetUserStateManager private
-; CreateCMSFromXmlInternal private
-; GetUserStoreInternal private
-; ParseManifestInternal private
-; CreateActContextInternal private
-; GetUserStateManagerInternal private
- CertCreateAuthenticodeLicense private
- CertTimestampAuthenticodeLicense private
- CertVerifyAuthenticodeLicense private
- CertFreeAuthenticodeSignerInfo private
- CertFreeAuthenticodeTimestamperInfo private
- _AxlPublicKeyBlobToPublicKeyToken private
- _AxlRSAKeyValueToPublicKeyToken private
- _AxlGetIssuerPublicKeyHash private
-#endif // FEATURE_FUSION
-
-;
-; win64 common
-;
-#ifdef _WIN64
- GetRuntimeStackWalkInfo
-#endif
-
- Nirvana_Dummy @24 NONAME PRIVATE
-
-#endif //FEATURE_CORECLR
IDS_EE_LOAD_BAD_MAIN_SIG "Main method for type '%1' has invalid signature."
IDS_EE_LOAD_CIRCULAR_DEPENDENCY "A circular dependency was detected when loading file or assembly '%1'."
-#ifdef FEATURE_CORECLR
IDS_EE_FILE_NOT_FOUND "File or assembly name '%1' was not found."
-#else
- IDS_EE_FILE_NOT_FOUND "File or assembly name '%1', or one of its dependencies, was not found."
-#endif
IDS_EE_TOO_MANY_OPEN_FILES "The system cannot open file '%1'. There may be too many open files."
IDS_EE_SHARING_VIOLATION "Cannot access file '%1' because it is being used by another process."
IDS_EE_CANNOT_HAVE_ASSEMBLY_SPEC "Unexpected assembly-qualifier in a typename."
IDS_EE_NEEDS_ASSEMBLY_SPEC "Typename needs an assembly qualifier."
-#ifdef FEATURE_CORECLR
IDS_EE_FILELOAD_ERROR_GENERIC "Could not load file or assembly '%1'. %2"
-#else
- IDS_EE_FILELOAD_ERROR_GENERIC "Could not load file or assembly '%1' or one of its dependencies. %2"
-#endif
IDS_EE_CRYPTO_UNKNOWN_OPERATION "Unknown import key operation specified."
IDS_CLASSLOAD_OVERLAPPING_INTERFACES "The type '%1' in assembly '%2' has a contracting interface set for some instantiations"
-#ifdef FEATURE_CORECLR
IDS_CLASSLOAD_32BITCLRLOADING64BITASSEMBLY "Attempted to load a 64-bit assembly on a 32-bit platform."
-#else // !FEATURE_CORECLR
- IDS_CLASSLOAD_32BITCLRLOADING64BITASSEMBLY "Attempted to load a 64-bit assembly on a 32-bit platform. Use ReflectionOnlyLoad() instead if trying to load for reflection purposes."
-#endif // FEATURE_CORECLR
IDS_CLASSLOAD_CONSTRAINT_MISMATCH_ON_IMPLICIT_OVERRIDE "Method '%3' on type '%1' from assembly '%2' tried to implicitly override a method with weaker type parameter constraints."
IDS_CLASSLOAD_CONSTRAINT_MISMATCH_ON_IMPLICIT_IMPLEMENTATION "Method '%3' on type '%1' from assembly '%2' tried to implicitly implement an interface method with weaker type parameter constraints."
IDS_UNMARSHALABLE_DEMAND_OBJECT "The security object (Permission or PermissionSet) used for performing a Demand caused an error relating to serialization/deserialization."
IDS_EE_OBJECT_TO_VARIANT_NOT_SUPPORTED "Invalid managed/unmanaged type combination (Marshaling to and from COM VARIANTs isn't supported)."
IDS_EE_OBJECT_TO_ITF_NOT_SUPPORTED "Invalid managed/unmanaged type combination (Marshaling to and from COM interface pointers isn't supported)."
-#ifdef FEATURE_CORECLR
IDS_TYPE_INHERITANCE_RULES_VIOLATED "Inheritance security rules violated by type: '%1'. Derived types must either match the security accessibility of the base type or be less accessible. If the base class has a non-transparent default constructor, the derived class must also have a default constructor, and the method inheritance rules apply across those two methods."
-#else // !FEATURE_CORECLR
- IDS_TYPE_INHERITANCE_RULES_VIOLATED "Inheritance security rules violated by type: '%1'. Derived types must either match the security accessibility of the base type or be less accessible."
-#endif // FEATURE_CORECLR
IDS_METHOD_INHERITANCE_RULES_VIOLATED "Inheritance security rules violated while overriding member: '%1'. Security accessibility of the overriding method must match the security accessibility of the method being overriden."
IDS_CRITICAL_METHOD_ACCESS_DENIED "Attempt to access method %1 in violation of security transparency rules failed."
-#ifdef FEATURE_CAS_POLICY
- IDS_E_LOADFROM_REMOTE_SOURCE "An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information."
- IDS_E_LOADFROM_REMOTE_SOURCE_MOTW "An attempt was made to load an assembly that was downloaded from a network location, which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this assembly is trusted, either remove the Zone marker from it or enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information."
-#endif // FEATURE_CAS_POLICY
IDS_CRITICAL_TYPE_ACCESS_DENIED "Attempt to access type %1 in violation of security transparency rules failed."
IDS_APPLICATION_ASSEMBLY_EXEC_DENIED "Application assemblies cannot be directly executed: %1"
IDS_REFLECTION_METHOD_ACCESS_DENIED "Application code cannot access %1 using Reflection."
IDS_E_CRITICAL_FIELD_ACCESS_DENIED "Attempt by security transparent method '%1' to access security critical field '%2' failed.%3"
IDS_E_CRITICAL_METHOD_ACCESS_DENIED "Attempt by security transparent method '%1' to access security critical method '%2' failed.%3"
IDS_E_CRITICAL_TYPE_ACCESS_DENIED "Attempt by security transparent method '%1' to access security critical type '%2' failed.%3"
-#ifdef FEATURE_CORECLR
IDS_E_DELEGATE_BINDING_TRANSPARENCY "A delegate of type '%1' cannot be bound to the method '%2' due to security transparency rules. Ensure the delegate type and the method being bound have compatible security transparency."
IDS_E_DELEGATE_FULLTRUST_ARPIC_1 "Delegate '%1' must be bound to a method in a fully-trusted assembly and the method must have the AllowReversePinvokeCallsAttribute."
IDS_E_DELEGATE_FULLTRUST_ARPIC_2 "Cannot create a Delegate for marshalling out unless it is bound to a method in a fully-trusted assembly and the method has the AllowReversePinvokeCallsAttribute."
-#endif
IDS_E_ACCESSING_PRIVATE_FRAMEWORK_CODE "Reflection invocation to internal or private types or members in the framework is not allowed."
IDS_EE_TORNSTATE "Unexpected change made to file '%1'."
BEGIN
IDS_ACCESS_EXCEPTION_CONTEXT_LEVEL2_APTCA "Assembly '%1' is marked with the AllowPartiallyTrustedCallersAttribute, and uses the level 2 security transparency model. Level 2 transparency causes all methods in AllowPartiallyTrustedCallers assemblies to become security transparent by default, which may be the cause of this exception."
IDS_ACCESS_EXCEPTION_CONTEXT_PT_TRANSPARENT "Assembly '%1' is partially trusted, which causes the CLR to make it entirely security transparent regardless of any transparency annotations in the assembly itself. In order to access security critical code, this assembly must be fully trusted."
-#ifdef FEATURE_APTCA
- IDS_ACCESS_EXCEPTION_CONTEXT_APTCA_KILLBIT "Assembly '%1' has had an APTCA killbit set for it, which prevents it from being used by partial trust or security transparent code."
- IDS_ACCESS_EXCEPTION_CONTEXT_CONDITIONAL_APTCA "Assembly '%1' is a conditionally APTCA assembly which is not enabled in the current AppDomain. To enable this assembly to be used by partial trust or security transparent code, please add assembly name '%2' to the the PartialTrustVisibleAssemblies list when creating the AppDomain."
-#endif // FEATURE_APTCA
END
// These strings are generated from within the EE for streams
BEGIN
IDS_ER_APPLICATION "Application: "
IDS_ER_UNKNOWN "unknown"
-#ifndef FEATURE_CORECLR
- IDS_ER_FRAMEWORK_VERSION "Framework Version: "
-#else // FEATURE_CORECLR
IDS_ER_FRAMEWORK_VERSION "CoreCLR Version: "
-#endif // !FEATURE_CORECLR
IDS_ER_UNHANDLEDEXCEPTION "Description: The process was terminated due to an unhandled exception."
IDS_ER_UNHANDLEDEXCEPTIONMSG "Exception Info: "
IDS_ER_MANAGEDFAILFAST "Description: The application requested process termination through System.Environment.FailFast(string message)."
IDS_DIALOG_BOX_IGNORE_BUTTON "&Ignore"
END
-#ifndef FEATURE_CORECLR
-// OOB servicing
-STRINGTABLE DISCARDABLE
-BEGIN
- IDS_EE_ASSEMBLY_ON_DENY_LIST "The assembly %1 that the application tried to load has a known vulnerability. Please go to %2 to find a fix for this issue."
-END
-#endif
-#ifdef FEATURE_CORECLR
STRINGTABLE DISCARDABLE
BEGIN
IDS_EE_BADMARSHAL_TYPE_ANSIBSTR "Marshalling as AnsiBStr is not supported"
IDS_EE_BADMARSHAL_TYPE_IDISPATCH "Marshalling as IDispatch is not supported"
IDS_EE_ERROR_IDISPATCH "IDispatch and IDispatchEx are not supported"
END
-#endif // FEATURE_CORECLR
#ifdef FEATURE_HOST_ASSEMBLY_RESOLVER
STRINGTABLE DISCARDABLE
#define IDS_E_TRANSPARENT_CALL_NATIVE 0x2120
#define IDS_E_TRANSPARENT_REFLECTION 0x2121
-#ifdef FEATURE_CORECLR
#define IDS_E_DELEGATE_BINDING_TRANSPARENCY 0x2122
-#endif
#define IDS_E_ACCESSING_PRIVATE_FRAMEWORK_CODE 0x2123
-#ifdef FEATURE_CORECLR
#define IDS_E_DELEGATE_FULLTRUST_ARPIC_1 0x2124
#define IDS_E_DELEGATE_FULLTRUST_ARPIC_2 0x2125
-#endif
#define IDS_ACCESS_EXCEPTION_CONTEXT_LEVEL2_APTCA 0x2200
#define IDS_ACCESS_EXCEPTION_CONTEXT_APTCA_KILLBIT 0x2201
#define IDS_E_PROF_TIMEOUT_WAITING_FOR_CONCURRENT_GC 0x251D
-#ifdef FEATURE_CORECLR
#define IDS_EE_LINK_FOR_ERROR_MESSAGES 0x2600
#define IDS_EE_LINK_FOR_DEBUGGING_MESSAGES 0x2601
-#endif
#define IDS_DIALOG_BOX_ABORT_BUTTON 0x2602
#define IDS_DIALOG_BOX_DEBUG_BUTTON 0x2603
#define IDS_EE_INTEROP_DLL_IMPORT_ON_USER_METHOD 0x262b
#endif
-#ifndef FEATURE_CORECLR
-#define IDS_EE_ASSEMBLY_ON_DENY_LIST 0x262c
-#endif
#ifdef FEATURE_COMINTEROP
#define IDS_EE_WINRT_WEAKREF_BAD_TYPE 0x262e
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_CORECLR
#define IDS_EE_BADMARSHAL_TYPE_ANSIBSTR 0x262f
#define IDS_EE_BADMARSHAL_TYPE_VBBYVALSTR 0x2630
#define IDS_EE_BADMARSHAL_TYPE_REFERENCECUSTOMMARSHALER 0x2631
#define IDS_EE_BADMARSHAL_TYPE_ASANYA 0x2633
#define IDS_EE_BADMARSHAL_TYPE_IDISPATCH 0x2634
#define IDS_EE_ERROR_IDISPATCH 0x2635
-#endif // FEATURE_CORECLR
#ifdef FEATURE_HOST_ASSEMBLY_RESOLVER
#define IDS_HOST_ASSEMBLY_RESOLVER_ASSEMBLY_ALREADY_LOADED_IN_CONTEXT 0x2636
#include "assembler.h"
#include "strongname.h"
-#ifndef FEATURE_CORECLR
-#include "LegacyActivationShim.h"
-#endif
#include <limits.h>
#include <fusion.h>
}
//==============================================================================================================
// Borrowed from VM\assembly.cpp
-#ifndef FEATURE_CORECLR
-HRESULT GetHash(__in LPWSTR moduleName,
- ALG_ID iHashAlg,
- BYTE** pbCurrentValue, // should be NULL
- DWORD *cbCurrentValue)
-{
- HRESULT hr = E_FAIL;
- HCRYPTPROV hProv = 0;
- HCRYPTHASH hHash = 0;
- DWORD dwCount = sizeof(DWORD);
- PBYTE pbBuffer = NULL;
- DWORD dwBufferLen;
- HANDLE hFile = INVALID_HANDLE_VALUE;
- HANDLE hMapFile = NULL;
-
- hFile = WszCreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ,
- 0, OPEN_EXISTING, 0, 0);
- if (hFile == INVALID_HANDLE_VALUE) return E_FAIL;
-
- dwBufferLen = SafeGetFileSize(hFile,NULL);
- if (dwBufferLen == 0xffffffff)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto exit;
- }
- hMapFile = WszCreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
- if (hMapFile == NULL) goto exit;
-
- pbBuffer = (PBYTE) MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
- if (pbBuffer == NULL) goto exit;
-
- // No need to late bind this stuff, all these crypto API entry points happen
- // to live in ADVAPI32.
-
- if ((!WszCryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) ||
- (!CryptCreateHash(hProv, iHashAlg, 0, 0, &hHash)) ||
- (!CryptHashData(hHash, pbBuffer, dwBufferLen, 0)) ||
- (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *) cbCurrentValue,
- &dwCount, 0))) {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto exit;
- }
-
- *pbCurrentValue = new BYTE[*cbCurrentValue];
- if (!(*pbCurrentValue)) {
- hr = E_OUTOFMEMORY;
- goto exit;
- }
-
- if(!CryptGetHashParam(hHash, HP_HASHVAL, *pbCurrentValue, cbCurrentValue, 0)) {
- hr = HRESULT_FROM_WIN32(GetLastError());
- delete[] *pbCurrentValue;
- *pbCurrentValue = 0;
- goto exit;
- }
-
- hr = S_OK;
-
- exit:
- if (pbBuffer) UnmapViewOfFile(pbBuffer);
- if (hMapFile) CloseHandle(hMapFile);
- CloseHandle(hFile);
- if (hHash)
- CryptDestroyHash(hHash);
- if (hProv)
- CryptReleaseContext(hProv, 0);
-
- return hr;
-}
-#endif // !FEATURE_CORECLR
//==============================================================================================================
void AsmMan::AddFile(__in __nullterminated char* szName, DWORD dwAttr, BinStr* pHashBlob)
if(m_pAssembly // and assembly is defined
&& m_pAssembly->ulHashAlgorithm) // and hash algorithm is defined...
{ // then try to compute it
-#ifndef FEATURE_CORECLR
- if(SUCCEEDED(GetHash(wzUniBuf,(ALG_ID)(m_pAssembly->ulHashAlgorithm),&pHash,&cbHash)))
- {
- tmp->pHash = new BinStr(pHash,cbHash);
- }
- else
-#endif // !FEATURE_CORECLR
{
pHash = NULL;
cbHash = 0;
m_pCurAsmRef = NULL;
return;
}
-#ifndef FEATURE_CORECLR
- if(m_pCurAsmRef->isAutodetect)
- {
- IAssemblyName* pIAsmName;
- HRESULT hr;
- // Convert name to Unicode
- WszMultiByteToWideChar(g_uCodePage,0,m_pCurAsmRef->szName,-1,wzUniBuf,dwUniBuf);
- hr = CreateAssemblyNameObject(&pIAsmName,wzUniBuf,CANOF_PARSE_DISPLAY_NAME,NULL);
- if(SUCCEEDED(hr))
- {
- // set enumeration criteria: what is known about AsmRef (besides name)
- if(m_pCurAsmRef->usVerMajor != (USHORT)0xFFFF)
- pIAsmName->SetProperty(ASM_NAME_MAJOR_VERSION,&(m_pCurAsmRef->usVerMajor),2);
- if(m_pCurAsmRef->usVerMinor != (USHORT)0xFFFF)
- pIAsmName->SetProperty(ASM_NAME_MINOR_VERSION,&(m_pCurAsmRef->usVerMinor),2);
- if(m_pCurAsmRef->usBuild != (USHORT)0xFFFF)
- pIAsmName->SetProperty(ASM_NAME_BUILD_NUMBER,&(m_pCurAsmRef->usBuild),2);
- if(m_pCurAsmRef->usRevision != (USHORT)0xFFFF)
- pIAsmName->SetProperty(ASM_NAME_REVISION_NUMBER,&(m_pCurAsmRef->usRevision),2);
- if(m_pCurAsmRef->pPublicKeyToken)
- pIAsmName->SetProperty(ASM_NAME_PUBLIC_KEY_TOKEN,
- m_pCurAsmRef->pPublicKeyToken->ptr(),
- m_pCurAsmRef->pPublicKeyToken->length());
- if(m_pCurAsmRef->pLocale)
- pIAsmName->SetProperty(ASM_NAME_CULTURE,
- m_pCurAsmRef->pLocale->ptr(),
- m_pCurAsmRef->pLocale->length());
-
- // enumerate assemblies
- IAssemblyEnum* pIAsmEnum = NULL;
- hr = CreateAssemblyEnum(&pIAsmEnum, NULL, pIAsmName, ASM_CACHE_GAC, NULL);
- if(SUCCEEDED(hr))
- {
- IAssemblyName* pIAsmNameFound;
- IAssemblyName* pIAsmNameLatestVer = NULL;
- ULONGLONG ullVer=0, ullVerLatest=0;
- DWORD dwVerHi, dwVerLo;
-
- // find the latest and greatest, if any
- for(;;)
- {
- pIAsmNameFound = NULL;
- hr = pIAsmEnum->GetNextAssembly(NULL,&pIAsmNameFound,0);
- if(SUCCEEDED(hr) && pIAsmNameFound)
- {
-
- pIAsmNameFound->GetVersion(&dwVerHi,&dwVerLo);
- ullVer = (ULONGLONG)dwVerHi;
- ullVer <<= sizeof(DWORD);
- ullVer |= dwVerLo;
- if(ullVer > ullVerLatest)
- {
- if(pIAsmNameLatestVer)
- pIAsmNameLatestVer->Release();
- ullVerLatest = ullVer;
- pIAsmNameLatestVer = pIAsmNameFound;
- }
- else
- pIAsmNameFound->Release();
- }
- else break;
- }
- // if found, fill the gaps
- if(pIAsmNameLatestVer)
- {
- DWORD cbSize=0;
- USHORT usDummy=0;
-
- if(m_pCurAsmRef->pPublicKeyToken == NULL)
- {
- cbSize = 1024;
- pIAsmNameLatestVer->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN,
- wzUniBuf, &cbSize);
- if(cbSize)
- {
- if((m_pCurAsmRef->pPublicKeyToken = new BinStr()))
- memcpy(m_pCurAsmRef->pPublicKeyToken->getBuff(cbSize),
- wzUniBuf, cbSize);
- }
- }
-
- if(m_pCurAsmRef->usVerMajor == (USHORT)0xFFFF)
- {
- cbSize = (DWORD)sizeof(WORD);
- pIAsmNameLatestVer->GetProperty(ASM_NAME_MAJOR_VERSION,
- &usDummy, &cbSize);
- m_pCurAsmRef->usVerMajor = usDummy;
- }
- if(m_pCurAsmRef->usVerMinor == (USHORT)0xFFFF)
- {
- cbSize = (DWORD)sizeof(WORD);
- pIAsmNameLatestVer->GetProperty(ASM_NAME_MINOR_VERSION,
- &usDummy, &cbSize);
- m_pCurAsmRef->usVerMinor = usDummy;
- }
- if(m_pCurAsmRef->usBuild == (USHORT)0xFFFF)
- {
- cbSize = (DWORD)sizeof(WORD);
- pIAsmNameLatestVer->GetProperty(ASM_NAME_BUILD_NUMBER,
- &usDummy, &cbSize);
- m_pCurAsmRef->usBuild = usDummy;
- }
- if(m_pCurAsmRef->usRevision == (USHORT)0xFFFF)
- {
- cbSize = (DWORD)sizeof(WORD);
- pIAsmNameLatestVer->GetProperty(ASM_NAME_REVISION_NUMBER,
- &usDummy, &cbSize);
- m_pCurAsmRef->usRevision = usDummy;
- }
-
- if(m_pCurAsmRef->pLocale == NULL)
- {
- cbSize = 1024;
- pIAsmNameLatestVer->GetProperty(ASM_NAME_CULTURE,
- wzUniBuf, &cbSize);
-
- if(cbSize > (DWORD)sizeof(WCHAR))
- {
- if((m_pCurAsmRef->pLocale = new BinStr()))
- memcpy(m_pCurAsmRef->pLocale->getBuff(cbSize),
- wzUniBuf, cbSize);
- }
- }
- pIAsmNameLatestVer->Release();
- }
- else
- report->warn("Failed to autodetect assembly '%s'\n",m_pCurAsmRef->szName);
- // if no assembly found, leave it as is, it might be not a GAC assembly
-
- pIAsmEnum->Release();
- }
- else
- report->error("Failed to enum assemblies %S, hr=0x%08X\n",wzUniBuf,hr);
- pIAsmName->Release();
- }
- else
- report->error("Failed to create assembly name object for %S, hr=0x%08X\n",wzUniBuf,hr);
- } // end if isAutodetect
-#endif // !FEATURE_CORECLR
m_AsmRefLst.PUSH(m_pCurAsmRef);
m_pCurAsmRef->tkTok = TokenFromRid(m_AsmRefLst.COUNT(),mdtAssemblyRef);
}
// character of the source ('@' for container).
if (*(((Assembler*)m_pAssembler)->m_wzKeySourceName) == L'@')
{
-#ifdef FEATURE_CORECLR
report->error("Error: ilasm on CoreCLR does not support getting public key from container.\n");
m_pCurAsmRef = NULL;
return;
-#else
- // Extract public key from container (works whether
- // container has just a public key or an entire key
- // pair).
- m_sStrongName.m_wzKeyContainer = &((Assembler*)m_pAssembler)->m_wzKeySourceName[1];
- if (FAILED(hr = LegacyActivationShim::StrongNameGetPublicKey_HRESULT(
- m_sStrongName.m_wzKeyContainer,
- NULL,
- 0,
- &m_sStrongName.m_pbPublicKey,
- &m_sStrongName.m_cbPublicKey)))
- {
- report->error("Failed to extract public key from '%S': 0x%08X\n",m_sStrongName.m_wzKeyContainer,hr);
- m_pCurAsmRef = NULL;
- return;
- }
- m_sStrongName.m_fFullSign = TRUE;
- m_sStrongName.m_dwPublicKeyAllocated = AsmManStrongName::AllocatedBySNApi;
-#endif // FEATURE_CORECLR
}
else
{
// from a consistent place.
if (m_sStrongName.m_fFullSign)
{
-#ifdef FEATURE_CORECLR
report->error("Error: ilasm on CoreCLR does not support full sign.\n");
m_pCurAsmRef = NULL;
return;
-#else
- m_sStrongName.m_pbPrivateKey = m_sStrongName.m_pbPublicKey;
- m_sStrongName.m_cbPrivateKey = m_sStrongName.m_cbPublicKey;
-
- m_sStrongName.m_pbPublicKey = NULL;
- m_sStrongName.m_cbPublicKey = NULL;
- m_sStrongName.m_dwPublicKeyAllocated = AsmManStrongName::NotAllocated;
-
- // Retrieve the public key portion as a byte blob.
- if (FAILED(hr = LegacyActivationShim::StrongNameGetPublicKey_HRESULT(
- NULL,
- m_sStrongName.m_pbPrivateKey,
- m_sStrongName.m_cbPrivateKey,
- &m_sStrongName.m_pbPublicKey,
- &m_sStrongName.m_cbPublicKey)))
- {
- report->error("Failed to extract public key: 0x%08X\n",hr);
- m_pCurAsmRef = NULL;
- return;
- }
-
- m_sStrongName.m_dwPublicKeyAllocated = AsmManStrongName::AllocatedBySNApi;
-#endif // FEATURE_CORECLR
}
}
}
#define ASMMAN_HPP
#include "strongname.h"
-#ifndef FEATURE_CORECLR
-#include "LegacyActivationShim.h"
-#endif
#include "specstrings.h"
struct AsmManFile
AsmManStrongName() { ZeroMemory(this, sizeof(*this)); }
~AsmManStrongName()
{
-#ifndef FEATURE_CORECLR
- if (m_dwPublicKeyAllocated == AllocatedBySNApi)
- {
- LegacyActivationShim::StrongNameFreeBuffer(m_pbPublicKey);
- }
- else
-#endif
if (m_dwPublicKeyAllocated == AllocatedByNew)
delete [] m_pbPublicKey;
};
-#if (0)
-template <class T>
-class FIFO
-{
-public:
- inline FIFO() { m_pHead = m_pTail = NULL; m_ulCount = 0;};
- inline ~FIFO() {T *val; while(val = POP()) delete val; };
- void PUSH(T *item)
- {
- m_pTemp = new LIST_EL <T>(item);
- if(m_pTail) m_pTail->m_Next = m_pTemp;
- m_pTail = m_pTemp;
- if(m_pHead == NULL) m_pHead = m_pTemp;
- m_ulCount++;
- };
- T* POP()
- {
- T* ret = NULL;
- if(m_pTemp = m_pHead)
- {
- m_pHead = m_pHead->m_Next;
- ret = m_pTemp->m_Ptr;
- delete m_pTemp;
- if(m_pHead == NULL) m_pTail = NULL;
- m_ulCount--;
- }
- return ret;
- };
- ULONG COUNT() { return m_ulCount; };
- T* PEEK(ULONG idx)
- {
- T* ret = NULL;
- ULONG i;
- if(idx < m_ulCount)
- {
- if(idx == m_ulCount-1) m_pTemp = m_pTail;
- else for(m_pTemp = m_pHead, i = 0; i < idx; m_pTemp = m_pTemp->m_Next, i++);
- ret = m_pTemp->m_Ptr;
- }
- return ret;
- };
-private:
- LIST_EL <T> *m_pHead;
- LIST_EL <T> *m_pTail;
- LIST_EL <T> *m_pTemp;
- ULONG m_ulCount;
-};
-#else
template <class T>
class FIFO
{
ULONG m_ulOffset;
ULONG m_ulArrLen;
};
-#endif
template <class T> struct Indx256
m_pDisp = NULL;
}
-#ifdef FEATURE_CORECLR
#ifdef FEATURE_PAL
if (g_loader != NULL)
{
g_loader->Finish();
}
#endif
-#else
- if (m_fDidCoInitialise)
- CoUninitialize();
-#endif // FEATURE_CORECLR
}
BOOL Assembler::Init()
{
-#ifdef FEATURE_CORECLR
#ifdef FEATURE_PAL
g_loader = CoreCLRLoader::Create(g_pszExeFile);
if (g_loader == NULL)
#else
metaDataGetDispenser = (MetaDataGetDispenserFunc)MetaDataGetDispenser;
#endif // FEATURE_PAL
-#else
- if(!m_fDidCoInitialise)
- {
- if (FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED)))
- return FALSE;
- m_fDidCoInitialise = TRUE;
- }
-#endif // FEATURE_CORECLR
if (m_pCeeFileGen != NULL) {
if (m_pCeeFile)
m_pCeeFileGen->DestroyCeeFile(&m_pCeeFile);
mdToken *ptkSpecial = NULL;
if(pszFullClassName == NULL) return mdTokenNil;
-#if (0)
- if (m_fInitialisedMetaData == FALSE)
- {
- if (FAILED(InitMetaData())) // impl. see WRITER.CPP
- {
- _ASSERTE(0);
- if(ppClass) *ppClass = NULL;
- return mdTokenNil;
- }
- }
-#endif
switch(strlen(pszFullClassName))
{
BinStr* Assembler::EncodeSecAttr(__in __nullterminated char* szReflName, BinStr* pbsSecAttrBlob, unsigned nProps)
{
unsigned cnt;
-#if (0)
- // Emit MemberRef for .ctor
- mdToken tkMscorlib = m_fIsMscorlib ? 1 : GetAsmRef("mscorlib");
- char buffer[64];
- BinStr *pbsSig = new BinStr();
-
- strcpy(buffer,"System.Security.Permissions.SecurityAction");
- mdToken tkSecAction = ResolveClassRef(tkMscorlib,buffer, NULL);
-
- pbsSig->appendInt8(IMAGE_CEE_CS_CALLCONV_HASTHIS);
- pbsSig->appendInt8(1); //corEmitInt(pbsSig,1);
- pbsSig->appendInt8(ELEMENT_TYPE_VOID);
- pbsSig->appendInt8(ELEMENT_TYPE_VALUETYPE);
- cnt = CorSigCompressToken(tkSecAction, pbsSig->getBuff(5));
- pbsSig->remove(5 - cnt);
-
- char* szName = new char[16];
- strcpy(szName,".ctor");
- MakeMemberRef(tkSecAttr,szName,pbsSig);
-#endif
// build the blob As BinStr
unsigned L = (unsigned) strlen(szReflName);
void EmitSecurityInfo(mdToken token,
PermissionDecl* pPermissions,
PermissionSetDecl*pPermissionSets);
-#ifndef FEATURE_CORECLR
- HRESULT AllocateStrongNameSignature();
- HRESULT StrongNameSign();
-#endif
BinStr* EncodeSecAttr(__in __nullterminated char* szReflName, BinStr* pbsSecAttrBlob, unsigned nProps);
// Custom values paraphernalia:
unsigned NumTypeDefs() {return m_TypeDefDList.COUNT();};
private:
HRESULT GetCAName(mdToken tkCA, __out LPWSTR *ppszName);
-#ifndef FEATURE_CORECLR
- HRESULT GetSignatureKey();
-#endif
};
#endif // Assember_h
/* fetch the next token, and return it Also set the yylval.union if the
lexical token also has a value */
-#if (0)
-
-#define IsAlpha(x) ((('A' <= (x))&&((x) <= 'Z'))||(('a' <= (x))&&((x) <= 'z')))
-#define IsDigit(x) (('0' <= (x))&&((x) <= '9'))
-#define IsAlNum(x) (IsAlpha(x) || IsDigit(x))
-#define IsValidStartingSymbol(x) (IsAlpha(x)||((x)=='#')||((x)=='_')||((x)=='@')||((x)=='$'))
-#define IsValidContinuingSymbol(x) (IsAlNum(x)||((x)=='_')||((x)=='@')||((x)=='$')||((x)=='?'))
-void SetSymbolTables() { ; }
-
-#else
BOOL _Alpha[128];
BOOL _Digit[128];
BOOL IsValidStartingSymbol(unsigned x) { return (x < 128)&&_ValidSS[x]; }
BOOL IsValidContinuingSymbol(unsigned x) { return (x < 128)&&_ValidCS[x]; }
-#endif
char* nextBlank(__in __nullterminated char* curPos)
{
#define PASMM (parser->assem->m_pManifest)
#define PENV (parser->penv)
-#if (0)
-
-#define nextchar parser->penv->pfn_nextchar
-#define Sym parser->penv->pfn_Sym
-#define NewStrFromToken parser->penv->pfn_NewStrFromToken
-#define NewStaticStrFromToken parser->penv->pfn_NewStaticStrFromToken
-#define GetDouble parser->penv->pfn_GetDouble
-
-void SetFunctionPtrs() {;}
-
-#else
PFN_NEXTCHAR nextchar;
GetDouble = PENV->pfn_GetDouble;
}
-#endif
static char* newStringWDel(__in __nullterminated char* str1, char delimiter, __in __nullterminated char* str3 = 0);
static char* newString(__in __nullterminated const char* str1);
else if (!_stricmp(szOpt, "DEB"))
{
pAsm->m_dwIncludeDebugInfo = 0x101;
-#ifdef FEATURE_CORECLR
// PDB is ignored under 'DEB' option for ilasm on CoreCLR.
// https://github.com/dotnet/coreclr/issues/2982
-#else
- pAsm->m_fGeneratePDB = TRUE;
-#endif
bNoDebug = FALSE;
WCHAR *pStr = EqualOrColon(argv[i]);
}
else if (!_stricmp(szOpt, "PDB"))
{
-#ifdef FEATURE_CORECLR
// 'PDB' option is ignored for ilasm on CoreCLR.
// https://github.com/dotnet/coreclr/issues/2982
-#else
- pAsm->m_fGeneratePDB = TRUE;
-#endif
bNoDebug = FALSE;
}
else if (!_stricmp(szOpt, "CLO"))
exitval = 1;
pParser->msg("Failed to write output file, error code=0x%08X\n",hr);
}
-#ifndef FEATURE_CORECLR
- else if (pAsm->m_pManifest->m_sStrongName.m_fFullSign)
- {
- // Strong name sign the resultant assembly.
- if(pAsm->m_fReportProgress) pParser->msg("Signing file with strong name\n");
- if (FAILED(hr=pAsm->StrongNameSign()))
- {
- exitval = 1;
- pParser->msg("Failed to strong name sign output file, error code=0x%08X\n",hr);
- }
- }
-#endif
if(bClock) cw.cEnd = GetTickCount();
#define ENC_ENABLED
-#ifdef ENC_ENABLED
if(exitval==0)
{
pAsm->m_fENCMode = TRUE;
}
} // end for(iFile)
} // end if(exitval==0)
-#endif
}
}
#pragma warning(pop)
#endif
-#ifndef FEATURE_CORECLR
-HINSTANCE GetModuleInst()
-{
- return (NULL);
-}
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_PAL
int main(int argc, char* str[])
{
psc->dwStart = m_pAssembler->m_CurPC;
psc->pSuperScope = m_pCurrScope;
-#if(0)
- LinePC *pLPC = new LinePC;
- if(pLPC)
- {
- pLPC->Line = m_pAssembler->m_ulCurLine;
- pLPC->Column = m_pAssembler->m_ulCurColumn;
- pLPC->PC = m_pAssembler->m_CurPC;
- m_LinePCList.PUSH(pLPC);
- }
-#endif
m_pCurrScope->SubScope.PUSH(psc);
m_pCurrScope = psc;
}
if((pVD = m_Locals.PEEK(pAN->dwAttr))) pVD->bInScope = FALSE;
}
m_pCurrScope->dwEnd = m_pAssembler->m_CurPC;
-#if(0)
- LinePC *pLPC = new LinePC;
- if(pLPC)
- {
- pLPC->Line = m_pAssembler->m_ulCurLine;
- pLPC->Column = m_pAssembler->m_ulCurColumn;
- pLPC->PC = m_pAssembler->m_CurPC;
- m_LinePCList.PUSH(pLPC);
- }
-#endif
m_pCurrScope = m_pCurrScope->pSuperScope;
}
#include "assembler.h"
#include "ceefilegenwriter.h"
-#ifndef FEATURE_CORECLR
-#include "strongname.h"
-#include "LegacyActivationShim.h"
-#endif
#ifndef _MSC_VER
//cloned definition from ntimage.h that is removed for non MSVC builds
if(bClock) bClock->cMDInitBegin = GetTickCount();
-#ifdef FEATURE_CORECLR
hr = metaDataGetDispenser(CLSID_CorMetaDataDispenser,
IID_IMetaDataDispenserEx, (void **)&m_pDisp);
-#else
- hr = LegacyActivationShim::ClrCoCreateInstance(
- CLSID_CorMetaDataDispenser,
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_IMetaDataDispenserEx,
- (void **)&m_pDisp);
-#endif
if (FAILED(hr))
goto exit;
if(FAILED(hr = m_pEmitter->QueryInterface(IID_IMetaDataImport2, (void**)&m_pImporter)))
goto exit;
-#ifndef FEATURE_CORECLR
- hr = CoCreateInstance(CLSID_CorSymWriter_SxS,
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_ISymUnmanagedWriter,
- (void **)&m_pSymWriter);
- if(SUCCEEDED(hr))
- {
- if(m_pSymWriter) m_pSymWriter->Initialize((IUnknown*)m_pEmitter,
- m_wzOutputFileName,
- NULL,
- TRUE);
- }
- else
- {
- fprintf(stderr, "Error: QueryInterface(IID_ISymUnmanagedWriter) returns %X\n",hr);
- m_pSymWriter = NULL;
- }
-#endif // !FEATURE_CORECLR
//m_Parser = new AsmParse(m_pEmitter);
m_fInitialisedMetaData = TRUE;
return (BYTE) (wc - L'a' + 10);
}
-#ifndef FEATURE_CORECLR
-bool GetBytesFromHex (LPCSTR szPublicKeyHexString, ULONG cchPublicKeyHexString, BYTE** buffer, ULONG *cbBufferSize)
-{
- ULONG cchHex = cchPublicKeyHexString;
- if (cchHex % 2 != 0)
- return false;
- *cbBufferSize = cchHex / 2;
-
- *buffer = new BYTE[*cbBufferSize];
- if (!*buffer)
- return false;
-
- for (ULONG i = 0; i < *cbBufferSize; i++)
- {
- BYTE msn = HexToByte(*szPublicKeyHexString);
- BYTE lsn = HexToByte(*(szPublicKeyHexString + 1));
- if (msn == 0xFF || lsn == 0xFF)
- {
- delete[] *buffer;
- return false;
- }
-
- (*buffer)[i] = (BYTE) ( (msn << 4) | lsn );
- szPublicKeyHexString += 2;
- }
-
- return true;
-}
-
-HRESULT Assembler::GetSignatureKey()
-{
- HRESULT hr = S_OK;
- ULONG cbSize = 0;
- void * pvData = NULL;
- LPWSTR pName = NULL;
-
- CustomDescrList* pCDList = &m_pManifest->m_pAssembly->m_CustomDescrList;
-
- for (ULONG i = 0;i < pCDList->COUNT(); i++)
- {
- CustomDescr* pCD = pCDList->PEEK(i);
-
- if(pCD->pBlob)
- {
- pvData = (void *)(pCD->pBlob->ptr());
- cbSize = pCD->pBlob->length();
- pCD->tkOwner = m_pManifest->m_pAssembly->tkTok;
- mdToken tkOwnerType, tkTypeType = TypeFromToken(pCD->tkType);
-
- if (GetCAName(pCD->tkType, &pName) != S_OK)
- continue;
-
- if (wcscmp(pName, L"System.Reflection.AssemblySignatureKeyAttribute") == 0)
- {
- if (cbSize < sizeof(WORD) || GET_UNALIGNED_VAL16(pvData) != 1)
- {
- hr = E_FAIL;
- break;;
- }
- pvData = (unsigned char *)pvData + sizeof(WORD);
- cbSize -= sizeof(WORD);
-
- // String is stored as compressed length, UTF8.
- if (*(const BYTE*)pvData != 0xFF)
- {
- PCCOR_SIGNATURE sig = (PCCOR_SIGNATURE)pvData;
- cbSize -= CorSigUncompressedDataSize(sig);
- DWORD len = CorSigUncompressData(sig);
- pvData = (void *)sig;
- if (cbSize < len)
- {
- hr = E_FAIL;
- break;
- }
-
- AsmManStrongName *pSN = &m_pManifest->m_sStrongName;
- GetBytesFromHex((LPCSTR)pvData, len, &pSN->m_pbSignatureKey, &pSN->m_cbSignatureKey);
- }
-
- break;
- }
-
- if (pName)
- {
- delete pName;
- pName = NULL;
- }
- }
- }
-
- if (pName)
- delete pName;
- return hr;
-}
-
-HRESULT Assembler::AllocateStrongNameSignature()
-{
- HRESULT hr = S_OK;
- HCEESECTION hSection;
- DWORD dwDataLength;
- DWORD dwDataOffset;
- DWORD dwDataRVA;
- VOID *pvBuffer;
- AsmManStrongName *pSN = &m_pManifest->m_sStrongName;
-
- // Pulls the AssemblySignatureKey attribute from m_CustomDescrList
- // If present, populate the pSN->m_pbSignatureKey from the AssemblySignatureKeyAttribute blob
- if (FAILED(hr = GetSignatureKey()))
- {
- return hr;
- }
-
- // Determine size of signature blob.
- if (pSN->m_pbSignatureKey != NULL)
- {
- // If m_pbSignatureKey present use it, else fall back to using identity key.
- if (FAILED(hr = LegacyActivationShim::StrongNameSignatureSize_HRESULT(
- pSN->m_pbSignatureKey,
- pSN->m_cbSignatureKey,
- &dwDataLength)))
- {
- return hr;
- }
- }
- else if (FAILED(hr = LegacyActivationShim::StrongNameSignatureSize_HRESULT(
- pSN->m_pbPublicKey,
- pSN->m_cbPublicKey,
- &dwDataLength)))
- {
- return hr;
- }
-
- // Grab memory in the section for our stuff.
- if (FAILED(hr = m_pCeeFileGen->GetIlSection(m_pCeeFile,
- &hSection)))
- return hr;
-
- if (FAILED(hr = m_pCeeFileGen->GetSectionBlock(hSection,
- dwDataLength,
- 4,
- &pvBuffer)))
- return hr;
-
- // Where did we get that memory?
- if (FAILED(hr = m_pCeeFileGen->GetSectionDataLen(hSection,
- &dwDataOffset)))
- return hr;
-
- dwDataOffset -= dwDataLength;
-
- // Convert to an RVA.
- if (FAILED(hr = m_pCeeFileGen->GetMethodRVA(m_pCeeFile,
- dwDataOffset,
- &dwDataRVA)))
- return hr;
-
- // Emit the directory entry.
- if (FAILED(hr = m_pCeeFileGen->SetStrongNameEntry(m_pCeeFile,
- dwDataLength,
- dwDataRVA)))
- return hr;
-
- return S_OK;
-}
-
-HRESULT Assembler::StrongNameSign()
-{
- LPWSTR wszOutputFile;
- HRESULT hr = S_OK;
- AsmManStrongName *pSN = &m_pManifest->m_sStrongName;
-
- // Determine what the ouput PE was called.
- if (FAILED(hr = m_pCeeFileGen->GetOutputFileName(m_pCeeFile,
- &wszOutputFile)))
- return hr;
-
- // Update the output PE image with a strong name signature.
- if (FAILED(hr = LegacyActivationShim::StrongNameSignatureGeneration_HRESULT(
- wszOutputFile,
- pSN->m_wzKeyContainer,
- pSN->m_pbPrivateKey,
- pSN->m_cbPrivateKey,
- NULL,
- NULL)))
- {
- return hr;
- }
-
- return S_OK;
-}
-#endif // !FEATURE_CORECLR
BOOL Assembler::EmitFieldsMethods(Class* pClass)
{
if(bClock) bClock->cMDEmit1 = GetTickCount();
-#ifndef FEATURE_CORECLR
- // Allocate space for a strong name signature if we're delay or full
- // signing the assembly.
- if (m_pManifest->m_sStrongName.m_pbPublicKey)
- if (FAILED(hr = AllocateStrongNameSignature()))
- goto exit;
-#endif
if(bClock) bClock->cMDEmit2 = GetTickCount();
if(!Init()) goto exit; // close and re-open CeeFileGen and CeeFile
hr = S_OK;
-#ifndef FEATURE_CORECLR
- hr = CoCreateInstance(CLSID_CorSymWriter_SxS,
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_ISymUnmanagedWriter,
- (void **)&m_pSymWriter);
- if(SUCCEEDED(hr))
- {
- WCHAR* pwc = &wzOrigFileName[wcslen(wzOrigFileName)];
- wcscat_s(wzOrigFileName,MAX_SCOPE_LENGTH,W(".pdb"));
- if(m_pSymWriter) m_pSymWriter->Initialize((IUnknown*)m_pEmitter,
- wzOrigFileName,
- NULL,
- TRUE);
- *pwc = 0;
- }
- else
- {
- fprintf(stderr, "Error: CoCreateInstance(IID_ISymUnmanagedWriter) returns %X\n",hr);
- m_pSymWriter = NULL;
- }
-#endif
exit:
return hr;
pBaseMDEmit->Release();
}
-#if(0)
-//===================================================================================
- // release SymWriter interfaces
- if (m_pSymWriter != NULL)
- {
- m_pSymWriter->Close();
- m_pSymWriter->Release();
- m_pSymWriter = NULL;
- }
-
- hr = CoCreateInstance(CLSID_CorSymWriter_SxS,
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_ISymUnmanagedWriter,
- (void **)&m_pSymWriter);
- if(SUCCEEDED(hr))
- {
- WCHAR* pwc = &pwzOutputFilename[wcslen(pwzOutputFilename)];
- wcscat(pwzOutputFilename,L".pdb");
- if(m_pSymWriter) m_pSymWriter->Initialize((IUnknown*)m_pEmitter,
- pwzOutputFilename,
- NULL,
- TRUE);
- *pwc = 0;
- }
- else
- {
- fprintf(stderr, "Error: CoCreateInstance(IID_ISymUnmanagedWriter) returns %X\n",hr);
- m_pSymWriter = NULL;
- }
-
- m_fENCMode = FALSE;
- if(FAILED(hr=CreatePEFile(pwzOutputFilename)))
- report->msg("Could not create output file, error code=0x%08X\n",hr);
- m_fENCMode = TRUE;
-//=====================================================================================
-#endif
// release all interfaces
if (m_pSymWriter != NULL)
pszClassName = (char*)(pc1 ? pc1 : "");
pszNamespace = (char*)(pc2 ? pc2 : "");
-#if (0)
-
- if((!IsTdNested(dwClassAttrs)))
- {
- // take care of namespace, if any
- if(strcmp(pszNamespace,g_szNamespace))
- {
- if(strlen(g_szNamespace))
- {
- if(g_szAsmCodeIndent[0]) g_szAsmCodeIndent[strlen(g_szAsmCodeIndent)-2] = 0;
- szptr = &szString[0];
- szptr+=sprintf_s(szptr,SZSTRING_SIZE,"%s%s ",g_szAsmCodeIndent,UNSCOPE());
- sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),COMMENT("// end of namespace %s"),ProperName(g_szNamespace));
- printLine(GUICookie,szString);
- printLine(GUICookie,"");
- }
- strcpy_s(g_szNamespace,MAX_MEMBER_LENGTH,pszNamespace);
- if(strlen(g_szNamespace))
- {
- sprintf_s(szString,SZSTRING_SIZE,"%s%s %s",
- g_szAsmCodeIndent,KEYWORD(".namespace"), ProperName(g_szNamespace));
- printLine(GUICookie,szString);
- sprintf_s(szString,SZSTRING_SIZE,"%s%s",g_szAsmCodeIndent,SCOPE());
- printLine(GUICookie,szString);
- strcat_s(g_szAsmCodeIndent,MAX_MEMBER_LENGTH," ");
- }
- }
- }
-
-#endif
szptr = &szString[0];
szptr+=sprintf_s(szptr,SZSTRING_SIZE,"%s%s ",g_szAsmCodeIndent,KEYWORD(".class"));
}
}
-#if (0)
- /* Third, dump GC/EH info about the native methods, using the IPMap */
- IMAGE_DATA_DIRECTORY *pIPMap;
- if (g_pPELoader->IsPE32())
- {
- pIPMap = &g_pPELoader->ntHeaders32()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];
- }
- else
- {
- pIPMap = &g_pPELoader->ntHeaders64()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];
- }
- DWORD IPMapSize;
- const BYTE * ipmap;
- IPMapSize = VAL32(pIPMap->Size);
- g_pPELoader->getVAforRVA(VAL32(pIPMap->VirtualAddress), (void **) &ipmap);
-
- DumpNativeInfo(ipmap, IPMapSize);
-#endif
// If there were "ldptr", dump the .rdata section with labels
if(g_iPtrCount)
class NewArrayHolder;
BOOL WinRTSupported();
-#ifdef FEATURE_CORECLR
namespace AppX
{
#endif // DACCESS_COMPILE
};
-#else // FEATURE_CORECLR
-
-struct AppXRTInfo;
-typedef DPTR(AppXRTInfo) PTR_AppXRTInfo;
-
-//---------------------------------------------------------------------------------------------
-namespace AppX
-{
- // cleans up resources allocated in InitAppXRT()
- void ShutDown();
-
- // Returns true if process is immersive (or if running in mockup environment).
- // NOTE: a return value of true doesn't necessarily indicate that the process is a
- // real Metro app, e.g. it could be an ngen process compiling an AppX assembly.
- bool IsAppXProcess();
-
-#ifdef DACCESS_COMPILE
- bool DacIsAppXProcess();
-#endif // DACCESS_COMPILE
-
- // Returns true if process is immersive (or if running in mockup environment).
- // Use only in NOFAULT regions when you are 100% sure that code:IsAppXProcess has been already called.
- // This function does not initialize (no faults).
- bool IsAppXProcess_Initialized_NoFault();
-
- // Returns true if process is NGen worker compiling an AppX assembly.
- bool IsAppXNGen();
-
- // Returns true if the host OS supports immersive apps.
- inline bool IsAppXSupported()
- { return WinRTSupported() != FALSE; }
-
- LPCWSTR GetHeadPackageMoniker();
-
- HRESULT GetCurrentPackageId(
- __inout PUINT32 pBufferLength,
- __out PBYTE pBuffer);
-
- HRESULT GetCurrentPackageInfo(
- __in UINT32 dwFlags,
- __inout PUINT32 pcbBuffer,
- __out PBYTE pbBuffer,
- __out PUINT32 nCount);
-
- bool IsAdaptiveApp();
- HRESULT GetCurrentPackageRoot(_Inout_ UINT32* length, _Out_opt_ PWSTR packageRoot);
- HRESULT GetWinMetadataDirForAdaptiveApps(_Out_ LPWSTR* winMetadDataDir);
-#ifdef FEATURE_APPX_BINDER
- enum FindFindInPackageFlags
- {
- FindFindInPackageFlags_None = 0,
- FindFindInPackageFlags_AllowLongFormatPath = 1,
- FindFindInPackageFlags_SkipCurrentPackageGraph = 2, // Only search in alt path
- };
-
- // If the function succeeds, pcchPathName is set to the length of the string that is copied to the buffer,
- // in characters, including the terminating null character, and the function returns S_OK. If the buffer
- // is too small, pcchPathName is set to the length of the buffer required (in characters),
- // including the terminating null character, and the function returns ERROR_INSUFFICIENT_BUFFER.
- HRESULT FindFileInCurrentPackage(
- __in PCWSTR pszFileName,
- __inout PUINT32 pcchPathName,
- __out PWSTR pszPathName,
- __in UINT32 uiFlags = PACKAGE_FILTER_CLR_DEFAULT,
- __in PCWSTR *rgwzAltPaths = NULL,
- __in UINT32 cAltPaths = 0,
- FindFindInPackageFlags findInCurrentPackageFlags = FindFindInPackageFlags_None);
-#endif // FEATURE_APPX_BINDER
-
- // Attempts to retrieve the AppContainer SID for the specified process.
- // For non-AppContainer processes the function will return S_FALSE and pAppContainerTokenInfo will be NULL.
- // For AppContainer processes the function will return S_OK and pAppContainerTokenInfo will contain data.
- // Note that there might be legitimate cases where this function fails (caller doesn't have permissions to
- // OpenProcess() for example) so any callers must account for such failures.
- // Use of NewArrayHolder permits method to reuse info for current process (dwPid == self) or to allocate
- // memory (dwPid != self). Cast the result to PTOKEN_APPCONTAINER_INFORMATION;
- HRESULT GetAppContainerTokenInfoForProcess(
- DWORD dwPid,
- NewArrayHolder<BYTE>& pbAppContainerTokenInfo, // Cast to PTOKEN_APPCONTAINER_INFORMATION on return.
- DWORD* pcbAppContainerTokenInfo = nullptr);
-
- // Called during NGen to pretend that we are in a certain package.
- HRESULT SetCurrentPackageForNGen(__in PCWSTR pszPackageFullName);
-}
-
-#endif // FEATURE_CORECLR
#else // FEATURE_APPX
RETAIL_CONFIG_STRING_INFO_EX(INTERNAL_TargetFrameworkMoniker, W("TargetFrameworkMoniker"), "Allows the test team to specify what TargetFrameworkMoniker to use.", CLRConfig::IgnoreHKLM | CLRConfig::IgnoreHKCU | CLRConfig::IgnoreConfigFiles | CLRConfig::IgnoreWindowsQuirkDB)
RETAIL_CONFIG_STRING_INFO_EX(INTERNAL_AppContextSwitchOverrides, W("AppContextSwitchOverrides"), "Allows default switch values defined in AppContext to be overwritten by values in the Config", CLRConfig::IgnoreEnv | CLRConfig::IgnoreHKLM | CLRConfig::IgnoreHKCU | CLRConfig::IgnoreWindowsQuirkDB | CLRConfig::ConfigFile_ApplicationFirst)
-#ifdef FEATURE_CORECLR
// For the proposal and discussion on why finalizers are not run on shutdown by default anymore in CoreCLR, see the API review:
// https://github.com/dotnet/corefx/issues/5205
#define DEFAULT_FinalizeOnShutdown (0)
-#else
-#define DEFAULT_FinalizeOnShutdown (1)
-#endif
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_FinalizeOnShutdown, W("FinalizeOnShutdown"), DEFAULT_FinalizeOnShutdown, "When enabled, on shutdown, blocks all user threads and calls finalizers for all finalizable objects, including live objects")
//
#ifdef FEATURE_CONSERVATIVE_GC
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_gcConservative, W("gcConservative"), 0, "Enables/Disables conservative GC")
#endif
-#ifdef FEATURE_CORECLR
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_gcServer, W("gcServer"), 0, "Enables server GC")
-#endif
CONFIG_STRING_INFO(INTERNAL_GcCoverage, W("GcCoverage"), "specify a method or regular expression of method names to run with GCStress")
CONFIG_STRING_INFO(INTERNAL_SkipGCCoverage, W("SkipGcCoverage"), "specify a list of assembly names to skip with GC Coverage")
RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(UNSUPPORTED_gcForceCompact, W("gcForceCompact"), "When set to true, always do compacting GC")
CONFIG_DWORD_INFO_DIRECT_ACCESS(INTERNAL_JitDebuggable, W("JitDebuggable"), "")
CONFIG_DWORD_INFO_EX(INTERNAL_JitDefaultFill, W("JitDefaultFill"), 0xDD, "In debug builds, initialize the memory allocated by the nra with this byte.", CLRConfig::REGUTIL_default)
CONFIG_DWORD_INFO_EX(INTERNAL_JitDirectAlloc, W("JitDirectAlloc"), 0, "", CLRConfig::REGUTIL_default)
-#if (!defined(DEBUG) && !defined(_DEBUG)) || (defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR))
+#if !defined(DEBUG) && !defined(_DEBUG)
#define INTERNAL_JitEnableNoWayAssert_Default 0
#else
#define INTERNAL_JitEnableNoWayAssert_Default 1
RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_DisableNativeImageLoadList, W("DisableNativeImageLoadList"), "Refuse to load native images corresponding to one of the assemblies on this semicolon-delimited list of assembly names.", CLRConfig::REGUTIL_default)
#endif
-#if defined(FEATURE_CORECLR) && defined(_TARGET_X86_)
+#if defined(_TARGET_X86_)
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_UseWindowsX86CoreLegacyJit, W("UseWindowsX86CoreLegacyJit"), 0, "Set to 1 to do all JITing with compatjit.dll. Only applicable to Windows x86 .NET Core.")
#endif
CONFIG_DWORD_INFO_EX(INTERNAL_MD_TlbImp_BreakOnErr, W("MD_TlbImp_BreakOnErr"), 0, "ASSERT when importing TLB into MD", CLRConfig::REGUTIL_default)
CONFIG_STRING_INFO_EX(INTERNAL_MD_TlbImp_BreakOnTypeImport, W("MD_TlbImp_BreakOnTypeImport"), "ASSERT when importing a type from TLB", (CLRConfig::LookupOptions) (CLRConfig::REGUTIL_default | CLRConfig::DontPrependCOMPlus_))
// MetaData - Desktop-only
-#ifndef FEATURE_CORECLR
-RETAIL_CONFIG_DWORD_INFO_EX(INTERNAL_MD_UseMinimalDeltas, W("MD_UseMinimalDeltas"), 1, "? Some MD modifications when applying EnC?", CLRConfig::REGUTIL_default)
-#endif //!FEATURE_CORECLR
CONFIG_DWORD_INFO_EX(INTERNAL_MD_WinMD_Disable, W("MD_WinMD_Disable"), 0, "Never activate the WinMD import adapter", CLRConfig::REGUTIL_default)
CONFIG_DWORD_INFO_EX(INTERNAL_MD_WinMD_AssertOnIllegalUsage, W("MD_WinMD_AssertOnIllegalUsage"), 0, "ASSERT if a WinMD import adapter detects a tool incompatibility", CLRConfig::REGUTIL_default)
RETAIL_CONFIG_DWORD_INFO(INTERNAL_NGenTaskDelayStart, W("NGenTaskDelayStart"), 0, "Use NGen Task delay start trigger, instead of critical idle task")
// Flag for cross-platform ngen: Removes all execution of managed or third-party code in the ngen compilation process.
-#ifdef FEATURE_CORECLR
RETAIL_CONFIG_DWORD_INFO(INTERNAL_Ningen, W("Ningen"), 1, "Enable no-impact ngen")
-#else
-// Ningen is off by default for desktop to reduce compat risk
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_Ningen, W("Ningen"), 0, "Enable no-impact ngen")
-#endif
CONFIG_DWORD_INFO(INTERNAL_NoASLRForNgen, W("NoASLRForNgen"), 0, "Turn off IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE bit in generated ngen images. Makes nidump output repeatable from run to run.")
RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_NgenAllowOutput, W("NgenAllowOutput"), 0, "If set to 1, the NGEN worker will bind to the parent console, thus allowing stdout output to work", CLRConfig::REGUTIL_default)
#endif //FEATURE_LAZY_COW_PAGES
-#ifdef FEATURE_CORECLR
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_ReadyToRun, W("ReadyToRun"), 1, "Enable/disable use of ReadyToRun native code") // On by default for CoreCLR
-#else
-RETAIL_CONFIG_DWORD_INFO(EXTERNAL_ReadyToRun, W("ReadyToRun"), 0, "Enable/disable use of ReadyToRun native code") // Off by default for desktop
-#endif
RETAIL_CONFIG_STRING_INFO(EXTERNAL_ReadyToRunExcludeList, W("ReadyToRunExcludeList"), "List of assemblies that cannot use Ready to Run images")
RETAIL_CONFIG_STRING_INFO(EXTERNAL_ReadyToRunLogFile, W("ReadyToRunLogFile"), "Name of file to log success/failure of using Ready to Run images")
RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_NativeImageRequire, W("NativeImageRequire"), 0, "", CLRConfig::REGUTIL_default)
CONFIG_DWORD_INFO_EX(INTERNAL_NestedEhOom, W("NestedEhOom"), 0, "", CLRConfig::REGUTIL_default)
RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_NO_SO_NOT_MAINLINE, W("NO_SO_NOT_MAINLINE"), 0, "", CLRConfig::REGUTIL_default)
-#if defined(CROSSGEN_COMPILE) || defined(FEATURE_CORECLR)
#define INTERNAL_NoGuiOnAssert_Default 1
-#else
-#define INTERNAL_NoGuiOnAssert_Default 0
-#endif
RETAIL_CONFIG_DWORD_INFO_EX(INTERNAL_NoGuiOnAssert, W("NoGuiOnAssert"), INTERNAL_NoGuiOnAssert_Default, "", CLRConfig::REGUTIL_default)
RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_NoProcedureSplitting, W("NoProcedureSplitting"), 0, "", CLRConfig::REGUTIL_default)
CONFIG_DWORD_INFO_EX(INTERNAL_NoStringInterning, W("NoStringInterning"), 1, "Disallows string interning. I see no value in it anymore.", CLRConfig::REGUTIL_default)
SEMAPHORE_COOKIE m_semaphore;
};
-#if defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
HMODULE GetCLRModule ();
-#endif // defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
#ifndef FEATURE_NO_HOST
/*
// import mscoree.idl for BucketParameters definition
import "mscoree.idl";
-#ifndef FEATURE_CORECLR
-import "hstring.idl";
-#endif //!FEATURE_CORECLR
-#ifndef FEATURE_CORECLR
-interface IActivationFactory;
-cpp_quote("interface IActivationFactory;")
-
-interface IWinRTClassActivator;
-cpp_quote("interface IWinRTClassActivator;")
-#endif //!FEATURE_CORECLR
cpp_quote("#if 0")
// IID_IPrivateManagedExceptionReporting : uuid{AD76A023-332D-4298-8001-07AA9350DCA4}
cpp_quote("EXTERN_GUID(IID_IPrivateManagedExceptionReporting, 0xad76a023, 0x332d, 0x4298, 0x80, 0x01, 0x07, 0xaa, 0x93, 0x50, 0xdc, 0xa4);")
-#ifndef FEATURE_CORECLR
-// CLSID CLRRuntimeHostInternal : uuid(f7721072-bf57-476d-89f8-a7625d27683a)
-cpp_quote("EXTERN_GUID(CLSID_CLRRuntimeHostInternal, 0xf7721072, 0xbf57, 0x476d, 0x89, 0xf8, 0xa7, 0x62, 0x5d, 0x27, 0x68, 0x3a);")
-// IID ICLRRuntimeHostInternal : uuid{07C4E752-3CBA-4A07-9943-B5F206382178}
-cpp_quote("EXTERN_GUID(IID_ICLRRuntimeHostInternal, 0x07c4e752, 0x3cba, 0x4a07, 0x99, 0x43, 0xb5, 0xf2, 0x06, 0x38, 0x21, 0x78);")
-
-// CLSID_CLRShimControlInternal : uuid(62D02A5B-F527-44d8-80BC-650BBD3CB082)
-cpp_quote("EXTERN_GUID(CLSID_CLRShimControlInternal, 0x62d02a5b, 0xf527, 0x44d8, 0x80, 0xbc, 0x65, 0xb, 0xbd, 0x3c, 0xb0, 0x82);")
-
-// IID ICLRShimControlInternal : uuid{826AAAD7-717B-44f8-9BB0-7DAC368B85A5}
-cpp_quote("EXTERN_GUID(IID_ICLRShimControlInternal, 0x826AAAD7, 0x717b, 0x44f8, 0x9b, 0xb0, 0x7d, 0xac, 0x36, 0x8b, 0x85, 0xa5);")
-
-// CLSID_CLRActivationFactory : uuid{5B132A7D-DA8E-461b-A0F2-109141C768CB}
-cpp_quote("EXTERN_GUID(CLSID_CLRActivationFactory, 0x5b132a7d, 0xda8e, 0x461b, 0xa0, 0xf2, 0x10, 0x91, 0x41, 0xc7, 0x68, 0xcb );")
-
-// IID_ICLRActivationFactory : uuid{331F2F6C-385F-462c-9125-816712FB2BC6}
-cpp_quote("EXTERN_GUID(IID_ICLRActivationFactory, 0x331f2f6c, 0x385f, 0x462c, 0x91, 0x25, 0x81, 0x67, 0x12, 0xfb, 0x2b, 0xc6);")
-
-// IID_ICLRActivationFactory2 : uuid{035049E5-2658-40C0-9269-21C48D8F0748}
-cpp_quote("EXTERN_GUID(IID_ICLRActivationFactory2, 0x035049E5, 0x2658, 0x40C0, 0x92, 0x69, 0x21, 0xC4, 0x8D, 0x8F, 0x07, 0x48);")
-
-// IID IID_ICLRExecutionManager: uuid(1000A3E7-B420-4620-AE30-FB19B587AD1D)
-cpp_quote("EXTERN_GUID(IID_ICLRExecutionManager, 0x1000A3E7, 0xB420, 0x4620, 0xAE, 0x30, 0xFB, 0x19, 0xB5, 0x87, 0xAD, 0x1D);")
-#endif // !FEATURE_CORECLR
//*****************************************************************************
// Interface for exposing services from the EE to other DLLs of the CLR.
HRESULT GetBucketParametersForCurrentException([out]BucketParameters *pParams);
}
-#ifndef FEATURE_CORECLR
-/**************************************************************************************
- ** ICLRRuntimeHostInternal **
- ** This is the functionality used only by CLR internal tools that moved from being **
- ** flat APIs (loading the latest runtime) to something that is runtime-specific and **
- ** requires the runtime to be loaded. **
- **************************************************************************************/
-[
- uuid(07C4E752-3CBA-4A07-9943-B5F206382178),
- version(1.0),
- helpstring("CLR internal hosting interface for V4.0"),
- local
-]
-interface ICLRRuntimeHostInternal : IUnknown
-{
- HRESULT MetaDataGetDispenser(
- [in] REFCLSID rclsid,
- [in] REFIID riid,
- [out, iid_is(riid), retval] IUnknown **ppInterface);
-
- HRESULT GetAssemblyMDImport(
- [in] LPCWSTR wszFileName, // The scope (file name) to open.
- [in] REFIID riid, // Desired interface.
- [out, iid_is(riid), retval] IUnknown **ppIUnk); // Returned interface on success.
-
- HRESULT GetMetaDataInternalInterface(
- [in, size_is(cbData)] BYTE *pbData, // MetaData data.
- [in] ULONG cbData, // MetaData data size.
- [in] DWORD flags, // Flags.
- [in] REFIID riid, // Desired interface.
- [out, iid_is(riid), retval] LPVOID *ppInterface); // Returned interface.
-
- HRESULT GetMetaDataInternalInterfaceFromPublic(
- [in] IUnknown *pInterface, // Given interface.
- [in] REFIID riid, // Desired interface.
- [out, iid_is(riid), retval] LPVOID *ppInterface); // Returned interface.
-
- HRESULT GetMetaDataPublicInterfaceFromInternal(
- [in] IUnknown *pInterface, // Given interface.
- [in] REFIID riid, // Desired interface.
- [out, iid_is(riid), retval] LPVOID *ppInterface); // Returned interface.
-
- /**********************************************************************************
- ** Returns the version string that MD emitter should by default write to images.**
- ** Supersedes: GetCORRequiredVersion **
- **********************************************************************************/
- HRESULT GetImageVersionString(
- [out, size_is(*pcchBuffer), annotation("__out_ecount_opt(*pcchBuffer)")] LPWSTR pwzBuffer, // Returned version string.
- [in, out] DWORD *pcchBuffer); // Buffer size/version length.
-
- /**********************************************************************************
- ** Locks the given module for this runtime. The HRESULT is S_OK if it is the **
- ** runtime represented by this instance, S_FALSE if somebody beat us to it. **
- **********************************************************************************/
- HRESULT LockModuleForRuntime(
- [in] BYTE *pModuleBase, // Address where the module is mapped.
- [in] REFIID riid, // Desired interface.
- [out, iid_is(riid)] LPVOID *ppRuntime); // The owning runtime.
-
- /**********************************************************************************
- ** Asks the Shim to attempt a graceful shutdown of all other runtimes loaded **
- ** in this process, then to exit the process via ::ExitProcess(). V4+ runtimes **
- ** call this instead of ::ExitProcess(). **
- **********************************************************************************/
- HRESULT ShutdownAllRuntimesThenExit(
- [in] UINT exitCode); // Process exit code.
-
- /**********************************************************************************
- ** GetTrueOSVersion - Bypasses the OS compatibility shim **
- **********************************************************************************/
- HRESULT GetTrueOSVersion(
- [out, in] LPOSVERSIONINFO osvi); // OS Version.
-
- /**********************************************************************************
- ** Returns the runtime that a COM component with the given CLSID would be **
- ** activated in. Returns runtime represented by this instance for Fx types. **
- **********************************************************************************/
- HRESULT GetRuntimeForManagedCOMObject(
- [in] REFCLSID rclsid, // CLSID of the component.
- [in] REFIID riid, // Desired runtime interface.
- [out, iid_is(riid), retval] LPVOID *ppRuntime); // Returned runtime.
-}; // interface ICLRRuntimeHostInternal
-
-/**************************************************************************************
- ** ICLRShimControlInternal **
- ** This is the functionality used only by CLR internal tools that moved from being **
- ** flat APIs (loading the latest runtime) to controlshim behavior **
- **************************************************************************************/
-[
- uuid(826AAAD7-717B-44f8-9BB0-7DAC368B85A5),
- version(1.0),
- helpstring("CLR internal hosting interface for V4.0"),
- local
-]
-interface ICLRShimControlInternal : IUnknown
-{
- HRESULT SetShouldSkipSkuCheck(
- [in] BOOL bValue
- );
-}; // interface ICLRRuntimeHostInternal
-
-
-
-/**************************************************************************************
- ** ICLRActivationFactory **
- ** This is the functionality used only by CLR to provide in-proc **
- ** hosting **
- **************************************************************************************/
-[
- uuid(331F2F6C-385F-462c-9125-816712FB2BC6),
- version(1.0),
- helpstring("CLR internal activation factory for V4.5"),
- local
-]
-interface ICLRActivationFactory : IUnknown
-{
- HRESULT CreateFactory([in] LPCWSTR activatableClassId,
- [out, retval] IActivationFactory** factory);
-
-}; // interface ICLRActivationFactory
-
-/**************************************************************************************
- ** ICLRActivationFactory2 **
- ** This is functionality exposed by the CLR to enable hosting WinRT components in a **
- ** non-AppX process **
- **************************************************************************************/
-[
- uuid(035049E5-2658-40C0-9269-21C48D8F0748),
- version(1.0),
- helpstring("CLR internal activation factory for desktop WinRT activation"),
- local
-]
-interface ICLRActivationFactory2 : ICLRActivationFactory
-{
- HRESULT GetClassActivatorForApplication(HSTRING appPath, [out] IWinRTClassActivator** ppActivator);
-};
-
-typedef enum
-{
- PAUSE_APP_DOMAINS = 0x1
-
-} PauseFlags;
-
-[
- uuid(1000A3E7-B420-4620-AE30-FB19B587AD1D),
- version(1.0),
- helpstring("Pause and Resume Interface"),
- pointer_default(unique),
- local
-]
-interface ICLRExecutionManager : IUnknown
-{
- // Pause all managed threads
- // Parameters are ignored and reserved for future use.
- HRESULT Pause([in] DWORD dwAppDomainId, [in] DWORD dwFlags);
-
- // Resume managed threads
- // Parameters are ignored and reserved for future use.
- HRESULT Resume([in] DWORD dwAppDomainId);
-}
-#endif // !FEATURE_CORECLR
#define __field_ecount(EHCount)
#endif
-#ifdef FEATURE_CORECLR
#undef _Ret_bytecap_
#define _Ret_bytecap_(_Size)
-#endif
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#endif //FEATURE_MAIN_CLR_MODULE_USES_CORE_NAME
-#ifdef FEATURE_CORECLR
#define MSCOREE_SHIM_W MAIN_CLR_DLL_NAME_W
#define MSCOREE_SHIM_A MAIN_CLR_DLL_NAME_A
-#else
-#define MSCOREE_SHIM_W L"mscoree.dll"
-#define MSCOREE_SHIM_A "mscoree.dll"
-#endif // FEATURE_CORECLR
#define SWITCHOUT_HANDLE_VALUE ((HANDLE)(LONG_PTR)-2)
CORCOMPILE_CODEGEN_PROFILING = 0x0004, // supports profiling
CORCOMPILE_CODEGEN_PROF_INSTRUMENTING = 0x0008, // code is instrumented to collect profile count info
-#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR)
- CORCOMPILE_CODEGEN_USE_RYUJIT = 0x0100, // code is generated by Ryu JIT
-#endif
};
-#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR)
-bool UseRyuJit();
-#endif
// Used for INativeImageInstallInfo::GetConfigMask()
// A bind will ask for the particular bits it needs set; if all bits are set, it is a match. Additional
typedef enum
{
-#ifdef FEATURE_CORECLR
CORECLR_INFO,
CROSSGEN_COMPILER_INFO,
-#else
- CLR_INFO,
- NGEN_COMPILER_INFO,
-#endif
NUM_RUNTIME_DLLS
} CorCompileRuntimeDlls;
};
-#ifndef FEATURE_CORECLR
-enum CorCompileDependencyInfo
-{
-#ifdef FEATURE_APTCA
- CORCOMPILE_DEPENDENCY_IS_APTCA = 0x1,
- CORCOMPILE_DEPENDENCY_IS_CAPTCA = 0x2,
-#endif //FEATURE_APTCA
-
- CORCOMPILE_DEPENDENCY_PEKIND_MASK = 0xff00,
- CORCOMPILE_DEPENDENCY_PEKIND_SHIFT = 8,
-};
-#endif //!FEATURE_CORECLR
struct CORCOMPILE_DEPENDENCY
CORCOMPILE_NGEN_SIGNATURE signNativeImage; // INVALID_NGEN_SIGNATURE if this a soft-bound dependency
-#ifdef FEATURE_APTCA
- // Win32 version info for tracking dependency references to strong-named assemblies with APTCA
- ULARGE_INTEGER uliFileVersion; // OS file version ~ NOT assembly version
-#endif //FEATURE_APTCA
-#ifndef FEATURE_CORECLR
- CorCompileDependencyInfo dependencyInfo; //Flags about the dependency
-#endif //!FEATURE_CORECLR
};
/*********************************************************************************/
CORINFO_MODULE_HANDLE *pHandle
) = 0;
-#ifndef FEATURE_CORECLR
- // Check if the assembly supports automatic NGen
- virtual BOOL SupportsAutoNGen(
- CORINFO_ASSEMBLY_HANDLE assembly
- ) = 0;
-
- // Tell OS to set cached signing level of the native image based on input assemblies
- virtual HRESULT SetCachedSigningLevel(
- HANDLE hNI,
- HANDLE *pModules,
- COUNT_T nModules
- ) = 0;
-#endif
// Checks to see if an up to date zap exists for the
// assembly
// create a PDB dumping all functions in hAssembly into pdbPath
extern "C" HRESULT __stdcall CreatePdb(CORINFO_ASSEMBLY_HANDLE hAssembly, BSTR pNativeImagePath, BSTR pPdbPath, BOOL pdbLines, BSTR pManagedPdbSearchPath, LPCWSTR pDiasymreaderPath);
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
extern bool g_fNGenMissingDependenciesOk;
-#endif
extern bool g_fNGenWinMDResilient;
class AppDomain;
class Assembly;
-#if !defined(FEATURE_CORECLR)
-class CorThreadpool : public ICorThreadpool
-{
-public:
- HRESULT STDMETHODCALLTYPE CorRegisterWaitForSingleObject(PHANDLE phNewWaitObject,
- HANDLE hWaitObject,
- WAITORTIMERCALLBACK Callback,
- PVOID Context,
- ULONG timeout,
- BOOL executeOnlyOnce,
- BOOL* pResult);
-
- HRESULT STDMETHODCALLTYPE CorBindIoCompletionCallback(HANDLE fileHandle, LPOVERLAPPED_COMPLETION_ROUTINE callback);
-
- HRESULT STDMETHODCALLTYPE CorUnregisterWait(HANDLE hWaitObject,HANDLE CompletionEvent, BOOL* pResult);
-
- HRESULT STDMETHODCALLTYPE CorQueueUserWorkItem(LPTHREAD_START_ROUTINE Function,PVOID Context,BOOL executeOnlyOnce, BOOL* pResult );
-
- HRESULT STDMETHODCALLTYPE CorCallOrQueueUserWorkItem(LPTHREAD_START_ROUTINE Function,PVOID Context,BOOL* pResult );
-
- HRESULT STDMETHODCALLTYPE CorCreateTimer(PHANDLE phNewTimer,
- WAITORTIMERCALLBACK Callback,
- PVOID Parameter,
- DWORD DueTime,
- DWORD Period,
- BOOL* pResult);
-
- HRESULT STDMETHODCALLTYPE CorDeleteTimer(HANDLE Timer, HANDLE CompletionEvent, BOOL* pResult);
-
- HRESULT STDMETHODCALLTYPE CorChangeTimer(HANDLE Timer,ULONG DueTime,ULONG Period, BOOL* pResult);
-
- HRESULT STDMETHODCALLTYPE CorSetMaxThreads(DWORD MaxWorkerThreads,
- DWORD MaxIOCompletionThreads);
-
- HRESULT STDMETHODCALLTYPE CorGetMaxThreads(DWORD *MaxWorkerThreads,
- DWORD *MaxIOCompletionThreads);
-
- HRESULT STDMETHODCALLTYPE CorGetAvailableThreads(DWORD *AvailableWorkerThreads,
- DWORD *AvailableIOCompletionThreads);
-};
-
-class CorGCHost : public IGCHost2
-{
-public:
- // IGCHost
- STDMETHODIMP STDMETHODCALLTYPE SetGCStartupLimits(
- DWORD SegmentSize,
- DWORD MaxGen0Size);
-
- STDMETHODIMP STDMETHODCALLTYPE Collect(
- LONG Generation);
-
- STDMETHODIMP STDMETHODCALLTYPE GetStats(
- COR_GC_STATS *pStats);
-
- STDMETHODIMP STDMETHODCALLTYPE GetThreadStats(
- DWORD *pFiberCookie,
- COR_GC_THREAD_STATS *pStats);
-
- STDMETHODIMP STDMETHODCALLTYPE SetVirtualMemLimit(
- SIZE_T sztMaxVirtualMemMB);
-
- // IGCHost2
- STDMETHODIMP STDMETHODCALLTYPE SetGCStartupLimitsEx(
- SIZE_T SegmentSize,
- SIZE_T MaxGen0Size);
-
-private:
-
- HRESULT _SetGCSegmentSize(SIZE_T SegmentSize);
- HRESULT _SetGCMaxGen0Size(SIZE_T MaxGen0Size);
-};
-
-class CorConfiguration : public ICorConfiguration
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE SetGCThreadControl(
- /* [in] */ IGCThreadControl __RPC_FAR *pGCThreadControl);
-
- virtual HRESULT STDMETHODCALLTYPE SetGCHostControl(
- /* [in] */ IGCHostControl __RPC_FAR *pGCHostControl);
-
- virtual HRESULT STDMETHODCALLTYPE SetDebuggerThreadControl(
- /* [in] */ IDebuggerThreadControl __RPC_FAR *pDebuggerThreadControl);
-
- virtual HRESULT STDMETHODCALLTYPE AddDebuggerSpecialThread(
- /* [in] */ DWORD dwSpecialThreadId);
-
- // This mechanism isn't thread-safe with respect to reference counting, because
- // the runtime will use the cached pointer without adding extra refcounts to protect
- // itself. So if one thread calls GetGCThreadControl & another thread calls
- // ICorHost::SetGCThreadControl, we have a race.
- static IGCThreadControl *GetGCThreadControl()
- {
- LIMITED_METHOD_CONTRACT;
-
- return m_CachedGCThreadControl;
- }
-
- static IGCHostControl *GetGCHostControl()
- {
- LIMITED_METHOD_CONTRACT;
-
- return m_CachedGCHostControl;
- }
-
- static IDebuggerThreadControl *GetDebuggerThreadControl()
- {
- LIMITED_METHOD_CONTRACT;
-
- return m_CachedDebuggerThreadControl;
- }
-
- static DWORD GetDebuggerSpecialThreadCount()
- {
- LIMITED_METHOD_CONTRACT;
-
- return m_DSTCount;
- }
-
- static DWORD *GetDebuggerSpecialThreadArray()
- {
- LIMITED_METHOD_CONTRACT;
-
- return m_DSTArray;
- }
-
- // Helper function that returns true if the thread is in the debugger special thread list
- static BOOL IsDebuggerSpecialThread(DWORD dwThreadId);
-
- // Helper function to update the thread list in the debugger control block
- static HRESULT RefreshDebuggerSpecialThreadList();
-
- // Clean up debugger thread control object, called at shutdown
- static void CleanupDebuggerThreadControl();
-
-private:
- // Cache the IGCThreadControl interface until the EE is started, at which point
- // we pass it through.
- static IGCThreadControl *m_CachedGCThreadControl;
- static IGCHostControl *m_CachedGCHostControl;
- static IDebuggerThreadControl *m_CachedDebuggerThreadControl;
-
- // Array of ID's of threads that should be considered "special" to
- // the debugging services.
- static DWORD *m_DSTArray;
- static DWORD m_DSTArraySize;
- static DWORD m_DSTCount;
-};
-
-class CorValidator : public IValidator
-{
-protected:
- CorValidator() {LIMITED_METHOD_CONTRACT;}
-
-public:
- STDMETHODIMP STDMETHODCALLTYPE Validate(
- IVEHandler *veh,
- IUnknown *pAppDomain,
- unsigned long ulFlags,
- unsigned long ulMaxError,
- unsigned long token,
- __in_z LPWSTR fileName,
- BYTE *pe,
- unsigned long ulSize);
-
- STDMETHODIMP STDMETHODCALLTYPE FormatEventInfo(
- HRESULT hVECode,
- VEContext Context,
- __out_ecount(ulMaxLength) LPWSTR msg,
- unsigned long ulMaxLength,
- SAFEARRAY *psa);
-};
-
-class CLRValidator : public ICLRValidator
-{
-protected:
- CLRValidator() {LIMITED_METHOD_CONTRACT;}
-
-public:
- STDMETHODIMP STDMETHODCALLTYPE Validate(
- IVEHandler *veh,
- unsigned long ulAppDomainId,
- unsigned long ulFlags,
- unsigned long ulMaxError,
- unsigned long token,
- __in_z LPWSTR fileName,
- BYTE *pe,
- unsigned long ulSize);
-
- STDMETHODIMP STDMETHODCALLTYPE FormatEventInfo(
- HRESULT hVECode,
- VEContext Context,
- __out_ecount(ulMaxLength) LPWSTR msg,
- unsigned long ulMaxLength,
- SAFEARRAY *psa);
-};
-
-class CorDebuggerInfo : public IDebuggerInfo
-{
-public:
- STDMETHODIMP IsDebuggerAttached(BOOL *pbAttached);
-};
-#endif // !defined(FEATURE_CORECLR)
class CorExecutionManager
: public ICLRExecutionManager
CorRuntimeHostBase()
:m_Started(FALSE),
m_cRef(0)
-#ifdef FEATURE_CORECLR
, m_fStarted(FALSE)
-#endif // FEATURE_CORECLR
{LIMITED_METHOD_CONTRACT;}
STDMETHODIMP_(ULONG) AddRef(void);
LONG m_cRef; // Ref count.
-#ifdef FEATURE_CORECLR
// This flag will be used to ensure that a CoreCLR host can invoke Start/Stop in pairs only.
BOOL m_fStarted;
BOOL m_fAppDomainCreated; // this flag is used when an appdomain can only create a single appdomain
-#endif // FEATURE_CORECLR
static ULONG m_Version; // Version of ICorRuntimeHost.
// Some functions are only available in ICLRRuntimeHost.
};
-#if !defined(FEATURE_CORECLR) // simple hosting
-class CorHost :
- public CorRuntimeHostBase, public ICorRuntimeHost, public CorThreadpool
- , public CorGCHost, public CorConfiguration
- , public CorValidator, public CorDebuggerInfo
- , public CorExecutionManager
-{
-public:
- CorHost() {WRAPPER_NO_CONTRACT;}
-
- // *** IUnknown methods ***
- STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
- STDMETHODIMP_(ULONG) AddRef(void)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::AddRef();
- }
- STDMETHODIMP_(ULONG) Release(void);
-
-
- // *** ICorRuntimeHost methods ***
- // Returns an object for configuring the runtime prior to
- // it starting. If the runtime has been initialized this
- // routine returns an error. See ICorConfiguration.
- STDMETHODIMP GetConfiguration(ICorConfiguration** pConfiguration);
-
-
- // Starts the runtime. This is equivalent to CoInitializeCor();
- STDMETHODIMP Start(void);
-
- STDMETHODIMP Stop();
-
- // Creates a domain in the runtime. The identity array is
- // a pointer to an array TYPE containing IIdentity objects defining
- // the security identity.
- STDMETHODIMP CreateDomain(LPCWSTR pwzFriendlyName, // Optional
- IUnknown* pIdentityArray, // Optional
- IUnknown ** pAppDomain)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::CreateDomain(pwzFriendlyName,pIdentityArray,pAppDomain);
- }
-
- // Returns the default domain.
- STDMETHODIMP GetDefaultDomain(IUnknown ** pAppDomain)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::GetDefaultDomain(pAppDomain);
- }
-
- // Enumerate currently existing domains.
- STDMETHODIMP EnumDomains(HDOMAINENUM *hEnum)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::EnumDomains(hEnum);
- }
-
- // Returns S_FALSE when there are no more domains. A domain
- // is passed out only when S_OK is returned.
- STDMETHODIMP NextDomain(HDOMAINENUM hEnum,
- IUnknown** pAppDomain)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::NextDomain(hEnum,pAppDomain);
- }
-
- // Close the enumeration releasing resources
- STDMETHODIMP CloseEnum(HDOMAINENUM hEnum)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::CloseEnum(hEnum);
- }
-
- STDMETHODIMP CreateDomainEx(LPCWSTR pwzFriendlyName,
- IUnknown* pSetup, // Optional
- IUnknown* pEvidence, // Optional
- IUnknown ** pAppDomain)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::CreateDomainEx(pwzFriendlyName,pSetup,pEvidence,pAppDomain);
- }
-
- // Create appdomain setup object that can be passed into CreateDomainEx
- STDMETHODIMP CreateDomainSetup(IUnknown** pAppDomainSetup)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::CreateDomainSetup(pAppDomainSetup);
- }
-
- // Create Evidence object that can be passed into CreateDomainEx
- STDMETHODIMP CreateEvidence(IUnknown** pEvidence)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::CreateEvidence(pEvidence);
- }
-
- // Unload a domain, releasing the reference will only release the
- // the wrapper to the domain not unload the domain.
- STDMETHODIMP UnloadDomain(IUnknown* pAppDomain)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::UnloadDomain(pAppDomain);
- }
-
- // Returns the threads domain if there is one.
- STDMETHODIMP CurrentDomain(IUnknown ** pAppDomain)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::CurrentDomain(pAppDomain);
- }
-
- // TODO: Following 4 APIs should be move to CorHost for V1.
- STDMETHODIMP CreateLogicalThreadState(); // Return code.
- STDMETHODIMP DeleteLogicalThreadState(); // Return code.
- STDMETHODIMP SwitchInLogicalThreadState( // Return code.
- DWORD *pFiberCookie // [in] Cookie that indicates the fiber to use.
- );
-
- STDMETHODIMP SwitchOutLogicalThreadState( // Return code.
- DWORD **pFiberCookie // [out] Cookie that indicates the fiber being switched out.
- );
-
- STDMETHODIMP LocksHeldByLogicalThread( // Return code.
- DWORD *pCount // [out] Number of locks that the current thread holds.
- )
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::LocksHeldByLogicalThread(pCount);
- }
-
- // Class factory hook-up.
- static HRESULT CreateObject(REFIID riid, void **ppUnk);
-
- STDMETHODIMP MapFile( // Return code.
- HANDLE hFile, // [in] Handle for file
- HMODULE *hMapAddress // [out] HINSTANCE for mapped file
- )
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::MapFile(hFile,hMapAddress);
- }
-};
-#endif // !defined(FEATURE_CORECLR)
class ConnectionNameTable;
typedef DPTR(class ConnectionNameTable) PTR_ConnectionNameTable;
#ifndef FEATURE_PAL
, public IPrivateManagedExceptionReporting /* This interface is for internal Watson testing only*/
#endif // FEATURE_PAL
-#ifdef FEATURE_CORECLR
, public ICLRRuntimeHost2
-#else
- , public CorThreadpool
- , public CorGCHost
- , public CorConfiguration
- , public CLRValidator
- , public CorDebuggerInfo
- , public ICLRRuntimeHost
- , public ICLRPrivRuntime
-#endif // FEATURE_CORECLR
, public CorExecutionManager
{
friend struct _DacGlobals;
// *** ICorRuntimeHost methods ***
-#ifndef FEATURE_CORECLR
- // Returns an object for configuring the runtime prior to
- // it starting. If the runtime has been initialized this
- // routine returns an error. See ICorConfiguration.
- STDMETHODIMP GetConfiguration(ICorConfiguration** pConfiguration);
-#endif // FEATURE_CORECLR
#ifndef FEATURE_PAL
// defined in IPrivateManagedExceptionReporting interface for internal Watson testing only
LPCWSTR pwzArgument,
DWORD *pReturnValue);
-#ifdef FEATURE_CORECLR
// *** ICLRRuntimeHost2 methods ***
STDMETHODIMP CreateAppDomainWithManager(
LPCWSTR wszFriendlyName,
LPCWSTR* argv,
DWORD* pReturnValue);
-#endif // !FEATURE_CORECLR
-#if !defined(FEATURE_CORECLR)
- /**********************************************************************************
- ** ICLRPrivRuntime Methods
- **********************************************************************************/
- STDMETHODIMP GetInterface(
- REFCLSID rclsid,
- REFIID riid,
- LPVOID * ppUnk);
-
- STDMETHODIMP CreateAppDomain(
- LPCWSTR pwzFriendlyName,
- ICLRPrivBinder * pBinder,
- LPDWORD pdwAppDomainId);
-
- STDMETHODIMP CreateDelegate(
- DWORD appDomainID,
- LPCWSTR wszAssemblyName,
- LPCWSTR wszClassName,
- LPCWSTR wszMethodName,
- LPVOID * ppvDelegate);
-
- STDMETHODIMP ExecuteMain(
- ICLRPrivBinder * pBinder,
- int * pRetVal);
-
-#endif // !FEATURE_CORECLR
static IHostControl *GetHostControl ()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return NULL;
-#else // FEATURE_CORECLR
- return m_HostControl;
-#endif // FEATURE_CORECLR
}
#ifdef FEATURE_INCLUDE_ALL_INTERFACES
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return NULL;
-#else // FEATURE_CORECLR
- return m_HostMemoryManager;
-#endif // FEATURE_CORECLR
}
static IHostMalloc *GetHostMalloc ()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return NULL;
-#else // FEATURE_CORECLR
- return m_HostMalloc;
-#endif // FEATURE_CORECLR
}
static IHostTaskManager *GetHostTaskManager ()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return NULL;
-#else // FEATURE_CORECLR
- return m_HostTaskManager;
-#endif // FEATURE_CORECLR
}
static IHostThreadpoolManager *GetHostThreadpoolManager ()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return NULL;
-#else // FEATURE_CORECLR
- return m_HostThreadpoolManager;
-#endif // FEATURE_CORECLR
}
static IHostIoCompletionManager *GetHostIoCompletionManager ()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return NULL;
-#else // FEATURE_CORECLR
- return m_HostIoCompletionManager;
-#endif // FEATURE_CORECLR
}
static IHostSyncManager *GetHostSyncManager ()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return NULL;
-#else // FEATURE_CORECLR
- return m_HostSyncManager;
-#endif // FEATURE_CORECLR
}
static IHostAssemblyManager *GetHostAssemblyManager()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return NULL;
-#else // FEATURE_CORECLR
- return m_HostAssemblyManager;
-#endif // FEATURE_CORECLR
}
static IHostGCManager *GetHostGCManager()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return NULL;
-#else // FEATURE_CORECLR
- return m_HostGCManager;
-#endif // FEATURE_CORECLR
}
static IHostSecurityManager *GetHostSecurityManager()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return NULL;
-#else // FEATURE_CORECLR
- return m_HostSecurityManager;
-#endif // FEATURE_CORECLR
}
static IHostPolicyManager *GetHostPolicyManager ()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return NULL;
-#else // FEATURE_CORECLR
- return m_HostPolicyManager;
-#endif // FEATURE_CORECLR
}
#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return 0;
-#else // FEATURE_CORECLR
- _ASSERTE (m_HostOverlappedExtensionSize != -1);
- return m_HostOverlappedExtensionSize;
-#endif // FEATURE_CORECLR
}
#ifdef FEATURE_INCLUDE_ALL_INTERFACES
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return NULL;
-#else // FEATURE_CORECLR
- return m_pHostDomainNeutralAsms;
-#endif // FEATURE_CORECLR
}
#endif // FEATURE_INCLUDE_ALL_INTERFACES
-#ifndef FEATURE_CORECLR
- static HRESULT SetFlagsAndHostConfig(STARTUP_FLAGS dwStartupFlags, LPCWSTR pwzHostConfigFile, BOOL fFinalize);
- static LPCWSTR GetHostConfigFile();
-
- static void GetDefaultAppDomainProperties(StringArrayList **ppPropertyNames, StringArrayList **ppPropertyValues);
-#endif // !FEATURE_CORECLR
static STARTUP_FLAGS GetStartupFlags();
-#ifndef FEATURE_CORECLR
- static HRESULT SetPropertiesForDefaultAppDomain(DWORD nProperties,
- __in_ecount(nProperties) LPCWSTR *pwszPropertyNames,
- __in_ecount(nProperties) LPCWSTR *pwszPropertyValues);
-
- static HRESULT SetAppDomainManagerType(LPCWSTR wszAppDomainManagerAssembly,
- LPCWSTR wszAppDomainManagerType,
- EInitializeNewDomainFlags dwInitializeDomainFlags);
-#endif // FEATURE_CORECLR
static LPCWSTR GetAppDomainManagerAsm();
static BOOL IsLoadFromBlocked(); // LoadFrom, LoadFile and Load(byte[]) are blocked in certain hosting scenarios
private:
-#ifdef FEATURE_CORECLR
// This flag indicates if this instance was the first to load and start CoreCLR
BOOL m_fFirstToLoadCLR;
// This flag indicates if the host has authenticated with us or not
BOOL m_fIsHostAuthenticated;
-#endif // FEATURE_CORECLR
// Helpers for both ICLRRuntimeHost2 and ICLRPrivRuntime
HRESULT _CreateAppDomain(
int nProperties,
LPCWSTR* pPropertyNames,
LPCWSTR* pPropertyValues,
-#if !defined(FEATURE_CORECLR)
- ICLRPrivBinder* pBinder,
-#endif
DWORD* pAppDomainID);
HRESULT _CreateDelegate(
static LPCWSTR s_wszAppDomainManagerType;
static EInitializeNewDomainFlags s_dwDomainManagerInitFlags;
-#if !defined(FEATURE_CORECLR)
- static StringArrayList s_defaultDomainPropertyNames;
- static StringArrayList s_defaultDomainPropertyValues;
-
-protected:
- static IHostMemoryManager *m_HostMemoryManager;
- static IHostMalloc *m_HostMalloc;
- static IHostTaskManager *m_HostTaskManager;
- static IHostThreadpoolManager *m_HostThreadpoolManager;
- static IHostIoCompletionManager *m_HostIoCompletionManager;
- static IHostSyncManager *m_HostSyncManager;
- static IHostAssemblyManager *m_HostAssemblyManager;
- static IHostGCManager *m_HostGCManager;
- static IHostSecurityManager *m_HostSecurityManager;
- static IHostPolicyManager *m_HostPolicyManager;
- static int m_HostOverlappedExtensionSize;
- static ICLRAssemblyReferenceList *m_pHostDomainNeutralAsms;
-
- static WCHAR m_wzHostConfigFile[_MAX_PATH];
-
- static BOOL m_dwFlagsFinalized;
- static DangerousNonHostedSpinLock m_FlagsLock; // protects the flags and host config
-#endif // !defined(FEATURE_CORECLR)
SVAL_DECL(STARTUP_FLAGS, m_dwStartupFlags);
};
{ 0xd41e4f1f, 0xa407, 0x11d1, {0x8b, 0xc9, 0x0, 0xc0, 0x4f, 0xa3, 0xa, 0x41 } }
-#ifndef FEATURE_CORECLR
-// See if we're set up to do a version check
-#if (VER_MAJORVERSION < 4)
-#error "Looks like major version isn't set correctly. Are you including product_version.h?"
-#endif
-
-// The following check has been added to ensure the right thing is done
-// for SxS compatibility of mscorsecimpl.dll when moving to a new framework
-// version.
-//
-// The library is registered using a full path and a GUID in the following location:
-// HKLM\SOFTWARE\Microsoft\Cryptography\Providers\Trust\*
-// With a new SxS version of the framework, we need to move to a new
-// GUID so older versions continue to work unimpacted.
-//
-// The check will fail when the runtime version changes; when it does,
-// please do the following:
-//
-// If the new version is NOT a SxS release with the version number in the #if,
-// update the version number in the #if below to the new version and you're done.
-//
-// If the new release is a SxS release, then there's a bit more work involved:
-// 1. Change COREE_POLICY_PROVIDER in CorPolicy.h to a new GUID.
-// 2. Update batchSetup to use the new GUID. To do so, update
-// all occurrences of the GUID in
-// ndp\clr\src\dlls\mscorsecimpl\mscorsecimpl.vrg
-// 3. Update "real" setup to use the new GUID. To do so, update
-// all occurrences of the GUID in
-// setupauthoring\netfx\clr\Components\mscorsec.dll.ddc
-// 4. Update the version number in the #if below.
-
-#if !(VER_MAJORVERSION == 4 && VER_MINORVERSION == 0)
-#error "The guid for mscorsecimpl needs to change when the runtime version changes"
-#endif
-
-// {A7F4C378-21BE-494e-BA0F-BB12C5D208C5}
-#define COREE_POLICY_PROVIDER \
-{ 0xa7f4c378, 0x21be, 0x494e, {0xba, 0x0f, 0xbb, 0x12, 0xc5, 0xd2, 0x08, 0xc5 } }
-
-#endif //#ifndef FEATURE_CORECLR
// This structure is returned from the winverify trust call, free up the structure
// using CoTaskMemAlloc except for COREE_POLICY_PROVIDER which uses LocalALLoc.
#include "peinformation.h"
//
-#ifndef FEATURE_CORECLR
-interface IILFingerprint;
-interface IILFingerprintFactory;
-#endif
interface IAssemblyName;
// PE images loaded through the runtime.
STDAPI RuntimeOpenImageByStream(IStream* pIStream, UINT64 AssemblyId, DWORD dwModuleId,
HCORMODULE* hHandle, DWORD *pdwLength, MDInternalImportFlags flags);
-#ifndef FEATURE_CORECLR
-// NOTE: Performance critical codepaths should cache the result of this function.
-STDAPI RuntimeGetILFingerprintForPath(LPCWSTR path, IILFingerprint **ppFingerprint);
-STDAPI RuntimeCreateCachingILFingerprintFactory(IILFingerprintFactory **ppILFingerprintFactory);
-#endif //!FEATURE_CORECLR
void RuntimeAddRefHandle(HCORMODULE hHandle);
STDAPI RuntimeReleaseHandle(HCORMODULE hHandle);
STDAPI RuntimeGetImageBase(HCORMODULE hHandle, LPVOID* base, BOOL bMapped, COUNT_T* dwSize);
-#ifndef FEATURE_CORECLR
-
-#include "iilfingerprint.h"
-
-#endif //!FEATURE_CORECLR
#endif // _CORPRIV_H_
// EOF =======================================================================
DEFINE_DACVAR(ULONG, PTR_SString, SString__s_Empty, SString::s_Empty)
#ifdef FEATURE_APPX
-#if defined(FEATURE_CORECLR)
DEFINE_DACVAR(ULONG, BOOL, dac__g_fAppX, ::g_fAppX)
-#else
-DEFINE_DACVAR(ULONG, PTR_AppXRTInfo, dac__g_pAppXRTInfo, ::g_pAppXRTInfo)
-#endif
#endif // FEATURE_APPX
DEFINE_DACVAR(ULONG, BOOL, SString__s_IsANSIMultibyte, SString::s_IsANSIMultibyte)
#ifdef FEATURE_CER
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pCriticalFinalizerObjectClass, ::g_pCriticalFinalizerObjectClass)
#endif
-#ifndef FEATURE_CORECLR
-DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pAsyncFileStream_AsyncResultClass, ::g_pAsyncFileStream_AsyncResultClass)
-#endif // !FEATURE_CORECLR
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pPredefinedArrayTypes, ::g_pPredefinedArrayTypes)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_TypedReferenceMT, ::g_TypedReferenceMT)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pByteArrayMT, ::g_pByteArrayMT)
DEFINE_DACVAR(ULONG, PTR_BYTE, WKS__gc_heap__background_saved_lowest_address, WKS::gc_heap::background_saved_lowest_address)
DEFINE_DACVAR(ULONG, PTR_BYTE, WKS__gc_heap__background_saved_highest_address, WKS::gc_heap::background_saved_highest_address)
-#ifdef FEATURE_CORECLR
#ifndef FEATURE_PAL
DEFINE_DACVAR(ULONG, HANDLE, dac__g_hContinueStartupEvent, ::g_hContinueStartupEvent)
#endif // !FEATURE_PAL
DEFINE_DACVAR(ULONG, DWORD, CorHost2__m_dwStartupFlags, CorHost2::m_dwStartupFlags)
-#endif // FEATURE_CORECLR
DEFINE_DACVAR(ULONG, HRESULT, dac__g_hrFatalError, ::g_hrFatalError)
DEFINE_DACVAR(ULONG, DWORD, PEFile__s_NGENDebugFlags, PEFile::s_NGENDebugFlags)
#endif //defined(DEBUGGING_SUPPORTED) && defined (FEATURE_PREJIT)
-#ifndef FEATURE_CORECLR
-DEFINE_DACVAR(ULONG, DWORD, AssemblyUsageLogManager__s_UsageLogFlags, AssemblyUsageLogManager::s_UsageLogFlags)
-#endif // FEATURE_CORECLR
#if defined(FEATURE_APPX_BINDER)
DEFINE_DACVAR(ULONG, PTR_CLRPrivBinderAppX, CLRPrivBinderAppX__s_pSingleton, CLRPrivBinderAppX::s_pSingleton)
import "oleidl.idl";
import "fusion.idl";
-#ifndef FEATURE_CORECLR
-import "binderngen.idl";
-#endif
cpp_quote("#ifdef _MSC_VER")
cpp_quote("#pragma once")
cpp_quote("#define EXPLICITBIND_FLAGS_NON_BINDABLE 0x0")
cpp_quote("#define EXPLICITBIND_FLAGS_EXE 0x1")
-#ifndef FEATURE_CORECLR
-#pragma midl_echo("HRESULT BindToSystem(IAssemblyName *pNameSystem, LPCWSTR pcwzSystemDirectory, IUnknown *pNIEva, IApplicationContext *pAppCtx, IAssembly **ppAsmOut, IBindResult **ppNIAsmOut, IFusionBindLog **ppdbglog);")
-
-#pragma midl_echo("HRESULT ExplicitBind(LPCWSTR wzPath, IApplicationContext *pAppCtx, DWORD dwFlags, IUnknown *pNIEva, IAssembly **ppAsmOut, IBindResult **ppNIAsmOut, IFusionBindLog **ppdbglog);")
-
-#pragma midl_echo("HRESULT GetBindContextFromApplicationContext(IApplicationContext *pAppCtx, IBindContext **ppBindCtx);")
-
-#pragma midl_echo("HRESULT SetApplicationContext_WinRTBinder(IApplicationContext * pAppCtx, IBindContext * pWinRTBinder);")
-
-// Used by InstallNativeImage() to extract dependency names from the NI's CORCOMPILE_DEPENDENCY_INFO records.
-#pragma midl_echo("STDAPI FusionGetAssemblyNameRefFromMDImport(IMetaDataAssemblyImport *pMDImport, /* This is really an mdAssemblyRef */ DWORD mdar, DWORD dwFlags, IAssemblyName **ppName);")
-
-#endif //!FEATURE_CORECLR
const class AppXBindResultImpl *_asAppXBindResultImpl;
#endif
-#ifndef FEATURE_CORECLR
- const class PEFingerprint *_asPEFingerprint;
-#endif //!FEATURE_CORECLR
const void *_pPreventEmptyUnion;
};
};
typedef Wrapper<LPCWSTR, DoNothing<LPCWSTR>, VoidDeleteFile, NULL> DeleteFileHolder;
#endif // WszDeleteFile
-#if !defined(FEATURE_CORECLR) || defined(FEATURE_CRYPTO)
+#if defined(FEATURE_CRYPTO)
// Crypto holders
FORCEINLINE void VoidCryptReleaseContext(HCRYPTPROV h) { CryptReleaseContext(h, 0); }
FORCEINLINE void VoidCryptDestroyHash(HCRYPTHASH h) { CryptDestroyHash(h); }
BOOL PAL_GetPALDirectoryWrapper(SString& pbuffer);
-#ifndef FEATURE_CORECLR
-//Temporarily providing direct OS Calls Till All of the Desktop CLR start using the above format
-inline DWORD
-SearchPathWrapper(
- _In_opt_ LPCWSTR lpPath,
- _In_ LPCWSTR lpFileName,
- _In_opt_ LPCWSTR lpExtension,
- _In_ BOOL getPath,
- _Out_ LPWSTR lpBuffer,
- _Out_opt_ LPWSTR * lpFilePart
- )
-{
- return SearchPathW(
- lpPath,
- lpFileName,
- lpExtension,
- getPath,
- lpBuffer,
- lpFilePart
- );
-}
-
-
-inline DWORD
-GetShortPathNameWrapper(
- _In_ LPCWSTR lpszLongPath,
- _Out_ LPWSTR lpszShortPath,
- _In_ DWORD cchBuffer
- )
-{
- return GetShortPathNameW(
- lpszLongPath,
- lpszShortPath,
- cchBuffer
- );
-}
-
-inline DWORD
-GetLongPathNameWrapper(
- _In_ LPCWSTR lpszShortPath,
- _Out_ LPWSTR lpszLongPath,
- _In_ DWORD cchBuffer
- )
-{
- return GetLongPathNameW(
- lpszShortPath,
- lpszLongPath,
- cchBuffer
- );
-}
-
-inline UINT GetTempFileNameWrapper(
- _In_ LPCWSTR lpPathName,
- _In_ LPCWSTR lpPrefixString,
- _In_ UINT uUnique,
- _Out_ LPWSTR lpTempFileName
- )
-{
- return GetTempFileNameW(
- lpPathName,
- lpPrefixString,
- uUnique,
- lpTempFileName
- );
-}
-
-inline DWORD GetTempPathWrapper(
- _In_ DWORD nBufferLength,
- _Out_ LPWSTR lpBuffer
- )
-{
- return GetTempPathW(
- nBufferLength,
- lpBuffer
- );
-}
-
-inline DWORD GetCurrentDirectoryWrapper(
- _In_ DWORD nBufferLength,
- _Out_ LPWSTR lpBuffer
- )
-{
- return GetCurrentDirectoryW(
- nBufferLength,
- lpBuffer
- );
-}
-
-inline DWORD
-GetModuleFileNameWrapper(
- _In_opt_ HMODULE hModule,
- _Out_ LPWSTR lpFilename,
- _In_ DWORD nSize
- )
-{
- return GetModuleFileNameW(
- hModule,
- lpFilename,
- nSize
- );
-}
-
-inline DWORD GetEnvironmentVariableWrapper(
- _In_opt_ LPCWSTR lpName,
- _Out_opt_ LPWSTR lpBuffer,
- _In_ DWORD nSize
- )
-{
- return GetEnvironmentVariableW(
- lpName,
- lpBuffer,
- nSize
- );
-}
-#endif //FEATURE_CORECLR
#endif //_WIN_PATH_APIS_WRAPPER_
#ifndef _METADATATRACKER_H_
#define _METADATATRACKER_H_
-#if defined(FEATURE_PREJIT) && (!defined(FEATURE_CORECLR) || defined(FEATURE_WINDOWSPHONE))
+#if defined(FEATURE_PREJIT) && defined(FEATURE_WINDOWSPHONE)
#define METADATATRACKER_DATA 1
#if !defined(DACCESS_COMPILE)
// WIN_PAL_ENDTRY
//
-#if !defined(FEATURE_CORECLR)
-
-#include "staticcontract.h"
-
-#define WIN_PAL_TRY_NAKED \
- { \
- bool __exHandled; __exHandled = false; \
- DWORD __exCode; __exCode = 0; \
- __try \
- {
-
-#define WIN_PAL_TRY \
- { \
- WIN_PAL_TRY_NAKED \
- WIN_PAL_TRY_HANDLER_DBG_BEGIN
-
-#define WIN_PAL_TRY_FOR_DLLMAIN(_reason) \
- { \
- WIN_PAL_TRY_NAKED \
- WIN_PAL_TRY_HANDLER_DBG_BEGIN_DLLMAIN(_reason)
-
-// Note: PAL_SEH_RESTORE_GUARD_PAGE is only ever defined in clrex.h, so we only restore guard pages automatically
-// when these macros are used from within the VM.
-#define WIN_PAL_SEH_RESTORE_GUARD_PAGE PAL_SEH_RESTORE_GUARD_PAGE
-
-#define WIN_PAL_EXCEPT_NAKED(Disposition) \
- } __except(__exCode = GetExceptionCode(), Disposition) { \
- __exHandled = true; \
- WIN_PAL_SEH_RESTORE_GUARD_PAGE
-
-#define WIN_PAL_EXCEPT(Disposition) \
- WIN_PAL_TRY_HANDLER_DBG_END \
- WIN_PAL_EXCEPT_NAKED(Disposition)
-
-#define WIN_PAL_EXCEPT_FILTER_NAKED(pfnFilter, pvFilterParameter) \
- } __except(__exCode = GetExceptionCode(), pfnFilter(GetExceptionInformation(), pvFilterParameter)) { \
- __exHandled = true; \
- WIN_PAL_SEH_RESTORE_GUARD_PAGE
-
-#define WIN_PAL_EXCEPT_FILTER(pfnFilter, pvFilterParameter) \
- WIN_PAL_TRY_HANDLER_DBG_END \
- WIN_PAL_EXCEPT_FILTER_NAKED(pfnFilter, pvFilterParameter)
-
-#define WIN_PAL_FINALLY_NAKED \
- } __finally { \
-
-#define WIN_PAL_FINALLY \
- WIN_PAL_TRY_HANDLER_DBG_END \
- WIN_PAL_FINALLY_NAKED
-
-#define WIN_PAL_ENDTRY_NAKED \
- } \
- } \
-
-#define WIN_PAL_ENDTRY \
- } \
- WIN_PAL_ENDTRY_NAKED_DBG \
- } \
- }
-
-#endif // !PAL_WIN_SEH
#if defined(_DEBUG_IMPL) && !defined(JIT_BUILD) && !defined(JIT64_BUILD) && !defined(_ARM_) // @ARMTODO
#ifndef __REGISTRYWRAPPER_H
#define __REGISTRYWRAPPER_H
-#if !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) && !defined(FEATURE_CORECLR)
-
-// Registry API wrappers
-
-LONG ClrRegCreateKeyEx(
- HKEY hKey,
- LPCWSTR lpSubKey,
- DWORD Reserved,
- __in_opt LPWSTR lpClass,
- DWORD dwOptions,
- REGSAM samDesired,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes,
- PHKEY phkResult,
- LPDWORD lpdwDisposition
- );
-
-LONG ClrRegOpenKeyEx(
- HKEY hKey,
- LPCWSTR lpSubKey,
- DWORD ulOptions,
- REGSAM samDesired,
- PHKEY phkResult
- );
-
-bool IsNgenOffline();
-
-#else
#define ClrRegCreateKeyEx RegCreateKeyExW
#define ClrRegOpenKeyEx RegOpenKeyExW
#define IsNgenOffline() false
-#endif
#endif // __REGISTRYWRAPPER_H
#ifndef _SHIMLOAD_H
#define _SHIMLOAD_H
-#ifndef FEATURE_CORECLR
-#include <delayimp.h>
-
-extern FARPROC __stdcall ShimDelayLoadHook(unsigned dliNotify, // What event has occurred, dli* flag.
- DelayLoadInfo *pdli); // Description of the event.
-
-//and one for safe mode
-extern FARPROC __stdcall ShimSafeModeDelayLoadHook(unsigned dliNotify, // What event has occurred, dli* flag.
- DelayLoadInfo *pdli); // Description of the event.
-
-#endif
//*****************************************************************************
// Sets/Gets the directory based on the location of the module. This routine
******************************************************************** robch */
void GetStringFromAddr(DWORD_PTR dwAddr, __out_ecount(cchMaxAssertStackLevelStringLen) LPSTR szString);
-#if defined(_TARGET_X86_) && defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#if defined(_TARGET_X86_) && !defined(FEATURE_PAL)
/****************************************************************************
* ClrCaptureContext *
*-------------------*
#define STRESS_HEAP
#endif
-#if !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
-#define STRESS_THREAD
-#endif
#define VERIFY_HEAP
#define GC_STATS
#endif
-#if !defined(FEATURE_CORECLR)
-#define EMIT_FIXUPS
-#endif
#if defined(_DEBUG) && !defined(DACCESS_COMPILE) && (defined(_TARGET_X86_) || defined(_TARGET_AMD64_))
// On x86/x64 Windows debug builds, respect the COMPlus_EnforceEEThreadNotRequiredContracts
// ALLOW_SXS_JIT_NGEN enables AltJit support for NGEN, via COMPlus_AltJitNgen / COMPlus_AltJitName.
// Note that if ALLOW_SXS_JIT_NGEN is defined, then ALLOW_SXS_JIT must be defined.
#define ALLOW_SXS_JIT
-#if defined(ALLOW_SXS_JIT)
#define ALLOW_SXS_JIT_NGEN
-#endif // ALLOW_SXS_JIT
-#if defined(FEATURE_CORECLR)
//master switch for gc suspension not based on hijacking
#define FEATURE_ENABLE_GCPOLL
-#endif //FEATURE_CORECLR
-#if defined(FEATURE_ENABLE_GCPOLL) && defined(_TARGET_X86_)
+#if defined(_TARGET_X86_)
//this enables a fast version of the GC Poll helper instead of the default portable one.
#define ENABLE_FAST_GCPOLL_HELPER
#endif // defined(FEATURE_ENABLE_GCPOLL) && defined(_TARGET_X86_)
#define PLATFORM_SUPPORTS_SAFE_THREADSUSPEND
#endif // !FEATURE_PAL
-#if !defined(PLATFORM_SUPPORTS_SAFE_THREADSUSPEND) && !defined(FEATURE_ENABLE_GCPOLL)
-#error "Platform must support either safe thread suspension or GC polling"
-#endif
#if defined(STRESS_HEAP) && defined(_DEBUG) && defined(FEATURE_HIJACK)
#define HAVE_GCCOVER
#endif
-#ifdef FEATURE_CORECLR
//Turns on a startup delay to allow simulation of slower and faster startup times.
#define ENABLE_STARTUP_DELAY
-#endif
#ifndef ALLOW_LOCAL_WORKER
#define FEATURE_PROFAPI_EVENT_LOGGING
#endif // defined(PROFILING_SUPPORTED)
-// Windows desktop supports the profiling API attach / detach feature.
-// This will eventually be supported on coreclr as well.
-#if defined(PROFILING_SUPPORTED) && !defined(FEATURE_CORECLR)
-#define FEATURE_PROFAPI_ATTACH_DETACH
-#endif
-
-// Windows desktop DAC builds need to see some of the data used in the profiling API
-// attach / detach feature, particularly Thread::m_dwProfilerEvacuationCounter
-#if defined(PROFILING_SUPPORTED_DATA) && !defined(FEATURE_CORECLR)
-#define DATA_PROFAPI_ATTACH_DETACH
-#endif
-
// MUST NEVER CHECK IN WITH THIS ENABLED.
// This is just for convenience in doing performance investigations in a checked-out enlistment.
// #define FEATURE_ENABLE_NO_RANGE_CHECKS
// are treated as potential pinned interior pointers. When enabled, the runtime flag COMPLUS_GCCONSERVATIVE
// determines dynamically whether GC is conservative. Note that appdomain unload, LCG and unloadable assemblies
// do not work reliably with conservative GC.
-#ifdef FEATURE_CORECLR
#define FEATURE_CONSERVATIVE_GC 1
-#endif
#if (defined(_TARGET_ARM_) && !defined(ARM_SOFTFP)) || defined(_TARGET_ARM64_)
#define FEATURE_HFA
#define FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
#endif // defined(FEATURE_CORESYSTEM)
-#if defined(FEATURE_PREJIT) && defined(FEATURE_CORECLR) && defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_PREJIT) && defined(FEATURE_CORESYSTEM)
// Desktop CLR allows profilers and debuggers to opt out of loading NGENd images, and to
// JIT everything instead. "FEATURE_TREAT_NI_AS_MSIL_DURING_DIAGNOSTICS" is roughly the
// equivalent for Apollo, where MSIL images may not be available at all.
// If defined, support interpretation.
#if !defined(CROSSGEN_COMPILE)
-#if defined(ALLOW_SXS_JIT) && !defined(FEATURE_PAL)
+#if !defined(FEATURE_PAL)
#define FEATURE_STACK_SAMPLING
#endif // defined (ALLOW_SXS_JIT)
#define WINDOWS_KERNEL32_DLLNAME_A "kernel32"
#define WINDOWS_KERNEL32_DLLNAME_W W("kernel32")
-#if defined(FEATURE_CORECLR)
#define CoreLibName_W W("System.Private.CoreLib")
#define CoreLibName_IL_W W("System.Private.CoreLib.dll")
#define CoreLibName_NI_W W("System.Private.CoreLib.ni.dll")
#define CoreLibSatelliteName_A "System.Private.CoreLib.resources"
#define CoreLibSatelliteNameLen 32
#define LegacyCoreLibName_A "mscorlib"
-#else // !defined(FEATURE_CORECLR)
-#define CoreLibName_W W("mscorlib")
-#define CoreLibName_IL_W W("mscorlib.dll")
-#define CoreLibName_NI_W W("mscorlib.ni.dll")
-#define CoreLibName_TLB_W W("mscorlib.tlb")
-#define CoreLibName_A "mscorlib"
-#define CoreLibName_IL_A "mscorlib.dll"
-#define CoreLibName_NI_A "mscorlib.ni.dll"
-#define CoreLibName_TLB_A "mscorlib.tlb"
-#define CoreLibNameLen 8
-#define CoreLibSatelliteName_A "mscorlib.resources"
-#define CoreLibSatelliteNameLen 18
-#define LegacyCoreLibName_A "mscorlib"
-#endif // defined(FEATURE_CORECLR)
class StringArrayList;
// Get the default resource location (mscorrc.dll for desktop, mscorrc.debug.dll for CoreCLR)
static CCompRC* GetDefaultResourceDll();
-#ifdef FEATURE_CORECLR
// Get the generic messages dll (Silverlight only, mscorrc.dll)
static CCompRC* GetFallbackResourceDll();
-#endif
static void ShutdownDefaultResourceDll();
static void GetDefaultCallbacks(
FPGETTHREADUICULTURENAMES* fpGetThreadUICultureNames,
fpGetThreadUICultureNames,
fpGetThreadUICultureId);
-#ifdef FEATURE_CORECLR
m_FallbackResourceDll.SetResourceCultureCallbacks(
fpGetThreadUICultureNames,
fpGetThreadUICultureId);
-#endif
}
#ifdef USE_FORMATMESSAGE_WRAPPER
static CCompRC m_DefaultResourceDll;
static LPCWSTR m_pDefaultResource;
-#ifdef FEATURE_CORECLR
// fallback resources if debug pack is not installed
static LONG m_dwFallbackInitialized;
static CCompRC m_FallbackResourceDll;
static LPCWSTR m_pFallbackResource;
-#endif
// We must map between a thread's int and a dll instance.
// Since we only expect 1 language almost all of the time, we'll special case
__out_opt LPCWSTR *pwszFileName, __out_opt size_t *pcchFileName,
__out_opt LPCWSTR *pwszExt, __out_opt size_t *pcchExt);
-#ifndef FEATURE_CORECLR
-void MakePath(__out_ecount (MAX_LONGPATH) register WCHAR *path,
- __in LPCWSTR drive,
- __in LPCWSTR dir,
- __in LPCWSTR fname,
- __in LPCWSTR ext);
-#endif
void MakePath(__out CQuickWSTR &path,
__in LPCWSTR drive,
static void FreeConfigString(__in __in_z LPWSTR name);
-#ifdef FEATURE_CORECLR
private:
-#endif //FEATURE_CORECLR
static LPWSTR EnvGetString(LPCWSTR name, BOOL fPrependCOMPLUS);
-#ifdef FEATURE_CORECLR
public:
-#endif //FEATURE_CORECLR
static BOOL UseRegistry();
BOOL fPrependCOMPLUS = TRUE);
public:
-#ifndef FEATURE_CORECLR
- static void AllowRegistryUse(BOOL fAllowUse);
-
-
-//*****************************************************************************
-// Open's the given key and returns the value desired. If the key or value is
-// not found, then the default is returned.
-//*****************************************************************************
- static long GetLong( // Return value from registry or default.
- LPCTSTR szName, // Name of value to get.
- long iDefault, // Default value to return if not found.
- LPCTSTR szKey=NULL, // Name of key, NULL==default.
- HKEY hKey=HKEY_LOCAL_MACHINE);// What key to work on.
-
-//*****************************************************************************
-// Open's the given key and returns the value desired. If the key or value is
-// not found, then the default is returned.
-//*****************************************************************************
- static long SetLong( // Return value from registry or default.
- LPCTSTR szName, // Name of value to get.
- long iValue, // Value to set.
- LPCTSTR szKey=NULL, // Name of key, NULL==default.
- HKEY hKey=HKEY_LOCAL_MACHINE);// What key to work on.
-
-//*****************************************************************************
-// Open's the given key and returns the value desired. If the key or value is
-// not found, then it's created
-//*****************************************************************************
- static long SetOrCreateLong( // Return value from registry or default.
- LPCTSTR szName, // Name of value to get.
- long iValue, // Value to set.
- LPCTSTR szKey=NULL, // Name of key, NULL==default.
- HKEY hKey=HKEY_LOCAL_MACHINE);// What key to work on.
-
-
-
-//*****************************************************************************
-// Set an entry in the registry of the form:
-// HKEY_CLASSES_ROOT\szKey\szSubkey = szValue. If szSubkey or szValue are
-// NULL, omit them from the above expression.
-//*****************************************************************************
- static BOOL SetKeyAndValue( // TRUE or FALSE.
- LPCTSTR szKey, // Name of the reg key to set.
- LPCTSTR szSubkey, // Optional subkey of szKey.
- LPCTSTR szValue); // Optional value for szKey\szSubkey.
-
-//*****************************************************************************
-// Delete an entry in the registry of the form:
-// HKEY_CLASSES_ROOT\szKey\szSubkey.
-//*****************************************************************************
- static LONG DeleteKey( // TRUE or FALSE.
- LPCTSTR szKey, // Name of the reg key to set.
- LPCTSTR szSubkey); // Subkey of szKey.
-
-//*****************************************************************************
-// Open the key, create a new keyword and value pair under it.
-//*****************************************************************************
- static BOOL SetRegValue( // Return status.
- LPCTSTR szKeyName, // Name of full key.
- LPCTSTR szKeyword, // Name of keyword.
- LPCTSTR szValue); // Value of keyword.
-
-//*****************************************************************************
-// Does standard registration of a CoClass with a progid.
-//*****************************************************************************
- static HRESULT RegisterCOMClass( // Return code.
- REFCLSID rclsid, // Class ID.
- LPCTSTR szDesc, // Description of the class.
- LPCTSTR szProgIDPrefix, // Prefix for progid.
- int iVersion, // Version # for progid.
- LPCTSTR szClassProgID, // Class progid.
- LPCTSTR szThreadingModel, // What threading model to use.
- LPCTSTR szModule, // Path to class.
- HINSTANCE hInst, // Handle to module being registered
- LPCTSTR szAssemblyName, // Optional assembly name
- LPCTSTR szVersion, // Optional Runtime Version (directry containing runtime)
- BOOL fExternal, // flag - External to mscoree.
- BOOL fRelativePath); // flag - Relative path in szModule
-
-//*****************************************************************************
-// Unregister the basic information in the system registry for a given object
-// class.
-//*****************************************************************************
- static HRESULT UnregisterCOMClass( // Return code.
- REFCLSID rclsid, // Class ID we are registering.
- LPCTSTR szProgIDPrefix, // Prefix for progid.
- int iVersion, // Version # for progid.
- LPCTSTR szClassProgID, // Class progid.
- BOOL fExternal); // flag - External to mscoree.
-
-//*****************************************************************************
-// Does standard registration of a CoClass with a progid.
-// NOTE: This is the non-side-by-side execution version.
-//*****************************************************************************
- static HRESULT RegisterCOMClass( // Return code.
- REFCLSID rclsid, // Class ID.
- LPCTSTR szDesc, // Description of the class.
- LPCTSTR szProgIDPrefix, // Prefix for progid.
- int iVersion, // Version # for progid.
- LPCTSTR szClassProgID, // Class progid.
- LPCTSTR szThreadingModel, // What threading model to use.
- LPCTSTR szModule, // Path to class.
- BOOL bInprocServer = true); // Whether we register the server as inproc or local
-
-//*****************************************************************************
-// Unregister the basic information in the system registry for a given object
-// class.
-// NOTE: This is the non-side-by-side execution version.
-//*****************************************************************************
- static HRESULT UnregisterCOMClass( // Return code.
- REFCLSID rclsid, // Class ID we are registering.
- LPCTSTR szProgIDPrefix, // Prefix for progid.
- int iVersion, // Version # for progid.
- LPCTSTR szClassProgID); // Class progid.
-
-//*****************************************************************************
-// Register a type library.
-//*****************************************************************************
- static HRESULT RegisterTypeLib( // Return code.
- REFGUID rtlbid, // TypeLib ID we are registering.
- int iVersion, // Typelib version.
- LPCTSTR szDesc, // TypeLib description.
- LPCTSTR szModule); // Path to the typelib.
-
-//*****************************************************************************
-// Remove the registry keys for a type library.
-//*****************************************************************************
- static HRESULT UnregisterTypeLib( // Return code.
- REFGUID rtlbid, // TypeLib ID we are registering.
- int iVersion); // Typelib version.
-
-#endif //#ifndef FEATURE_CORECLR
//*****************************************************************************
// (Optional) Initialize the config registry cache
private:
-#ifndef FEATURE_CORECLR
-
-//*****************************************************************************
-// Register the basics for a in proc server.
-//*****************************************************************************
- static HRESULT RegisterClassBase( // Return code.
- REFCLSID rclsid, // Class ID we are registering.
- LPCTSTR szDesc, // Class description.
- LPCTSTR szProgID, // Class prog ID.
- LPCTSTR szIndepProgID, // Class version independant prog ID.
- __out_ecount (cchOutCLSID) LPTSTR szOutCLSID, // CLSID formatted in character form.
- DWORD cchOutCLSID); // Out CLS ID buffer size in characters
-
-
-//*****************************************************************************
-// Delete the basic settings for an inproc server.
-//*****************************************************************************
- static HRESULT UnregisterClassBase( // Return code.
- REFCLSID rclsid, // Class ID we are registering.
- LPCTSTR szProgID, // Class prog ID.
- LPCTSTR szIndepProgID, // Class version independant prog ID.
- __out_ecount (cchOutCLSID) LPTSTR szOutCLSID, // Return formatted class ID here.
- DWORD cchOutCLSID); // Out CLS ID buffer size in characters
-
-#endif //#ifndef FEATURE_CORECLR
//*****************************************************************************
// Return TRUE if the registry value name might have been seen in the registry
return NtCurrentTeb()->ProcessEnvironmentBlock;
}
-#ifndef FEATURE_CORECLR
- static void* GetFiberDataPtr()
- {
- LIMITED_METHOD_CONTRACT;
- return ClrTeb::IsCurrentThreadAFiber()? GetCurrentFiber() : NULL;
- }
-
- static BOOL IsCurrentThreadAFiber()
- {
- return IsThreadAFiber();
- }
-#endif
static void* InvalidFiberPtrId()
{
BOOL FileExists(LPCWSTR filename);
-#ifndef FEATURE_CORECLR
-class FileLockHolder
-{
-public:
- FileLockHolder();
- ~FileLockHolder();
-
- virtual void Acquire(LPCWSTR lockName, HANDLE hInterrupt = 0, BOOL* pInterrupted = NULL);
- HRESULT AcquireNoThrow(LPCWSTR lockName, HANDLE hInterrupt = 0, BOOL* pInterrupted = NULL);
-
- static BOOL IsTaken(LPCWSTR lockName);
- void Release();
-private:
- HANDLE _hLock;
-};
-#endif // FEATURE_CORECLR
// a class for general x.x version info
class MajorMinorVersionInfo
pfnGetCLRFunction_t m_pfnGetCLRFunction;
};
-#if defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
// For DAC, we include this functionality only when EH SxS is enabled.
#define VALIDATECORECLRCALLBACKS()
#endif //_DEBUG
-#endif // defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
#ifdef FEATURE_CORRUPTING_EXCEPTIONS
BOOL IsClrHostedLegacyComObject(REFCLSID rclsid);
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-
-// No utilcode code should use the global LoadLibraryShim anymore. UtilCode::LoadLibraryShim will do
-// the right thing based on whether the hosted or non-hosted utilcode is linked to. Using the global
-// LoadLibraryShim will result in a deprecated use warning.
-
-#ifdef SELF_NO_HOST
-#define LEGACY_ACTIVATION_SHIM_LOAD_LIBRARY WszLoadLibrary
-#include "legacyactivationshim.h"
-#include "mscoreepriv.h"
-
-namespace UtilCode
-{
- inline HRESULT LoadLibraryShim(LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE *phModDll)
- {
- return LegacyActivationShim::LoadLibraryShim(szDllName, szVersion, pvReserved, phModDll);
- }
-};
-#else // SELF_NO_HOST
-namespace UtilCode
-{
- // Hosted environment
- HRESULT LoadLibraryShim(LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE *phModDll);
-};
-#endif // SELF_NO_HOST
-
-#endif // !FEATURE_CORECLR && !CROSSGEN_COMPILE
// Helper to support termination due to heap corruption
void EnableTerminationOnHeapCorruption();
-#if !defined(FEATURE_CORECLR)
-// On success, sets pwszProcessExePath (required) to full path to process EXE.
-HRESULT GetProcessExePath(LPCWSTR *pwszProcessExePath);
-#endif
namespace Clr { namespace Util
{
VPTR_CLASS(ReflectionModule)
VPTR_CLASS(AppDomain)
-#ifndef FEATURE_CORECLR // FEATURE_NATIVE_IMAGE_GENERATION
-VPTR_MULTI_CLASS(CompilationDomain, AppDomain)
-#endif
VPTR_CLASS(SharedDomain)
VPTR_CLASS(SystemDomain)
#define WszRegQueryValueExTrue RegQueryValueExW
#define WszRegQueryStringValueEx RegQueryValueExW
-#ifndef FEATURE_CORECLR
-#define WszRegDeleteKey RegDeleteKeyW
-#define WszRegCreateKeyEx ClrRegCreateKeyEx
-#define WszRegSetValueEx RegSetValueExW
-#define WszRegDeleteValue RegDeleteValueW
-#define WszRegLoadKey RegLoadKeyW
-#define WszRegUnLoadKey RegUnLoadKeyW
-#define WszRegRestoreKey RegRestoreKeyW
-#define WszRegReplaceKey RegReplaceKeyW
-#endif //#ifndef FEATURE_CORECLR
#define WszRegQueryInfoKey RegQueryInfoKeyW
#define WszRegEnumValue RegEnumValueW
BOOL m_failed;
CorInfoRegionKind m_currentRegionKind;
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
SString m_platformAssembliesPaths;
SString m_trustedPlatformAssemblies;
SString m_platformResourceRoots;
SString m_appPaths;
SString m_appNiPaths;
SString m_platformWinmdPaths;
-#endif // FEATURE_CORECLR || CROSSGEN_COMPILE
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
SString m_CLRJITPath;
bool m_fDontLoadJit;
#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
-#if defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#if !defined(NO_NGENPDB)
SString m_DiasymreaderPath;
#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
bool m_fForceFullTrust;
}
} m_assemblyDependencies;
-#ifndef FEATURE_CORECLR // No load lists on CoreCLR
- struct loadLists
- {
- loadLists() :
- m_loadAlwaysList(NULL),
- m_loadSometimesList(NULL),
- m_loadNeverList(NULL)
- {
- }
-
- SAFEARRAY *m_loadAlwaysList;
- SAFEARRAY *m_loadSometimesList;
- SAFEARRAY *m_loadNeverList;
-
- void SetLoadLists(SAFEARRAY *loadAlwaysList, SAFEARRAY *loadSometimesList, SAFEARRAY *loadNeverList)
- {
- m_loadAlwaysList = loadAlwaysList;
- m_loadSometimesList = loadSometimesList;
- m_loadNeverList = loadNeverList;
- }
-
- } m_loadLists;
-
- void SetLoadLists(SAFEARRAY *loadAlwaysList, SAFEARRAY *loadSometimesList, SAFEARRAY *loadNeverList)
- {
- m_loadLists.SetLoadLists(loadAlwaysList, loadSometimesList, loadNeverList);
- }
-
- void SetAssemblyHardBindList()
- {
- SAFEARRAY *loadAlwaysList = m_loadLists.m_loadAlwaysList;
- if (loadAlwaysList == NULL)
- {
- return;
- }
-
- LONG ubound = 0;
- IfFailThrow(SafeArrayGetUBound(loadAlwaysList, 1, &ubound));
-
- BSTR *pArrBstr = NULL;
- IfFailThrow(SafeArrayAccessData(loadAlwaysList, reinterpret_cast<void **>(&pArrBstr)));
-
- EX_TRY
- {
- _ASSERTE((ubound + 1) >= 0);
- m_pEECompileInfo->SetAssemblyHardBindList(reinterpret_cast<LPWSTR *>(pArrBstr), ubound + 1);
- }
- EX_CATCH
- {
- // If something went wrong, try to unlock the OLE array
- // Do not verify the outcome, as we can do nothing about it
- SafeArrayUnaccessData(loadAlwaysList);
- EX_RETHROW;
- }
- EX_END_CATCH_UNREACHABLE;
-
- IfFailThrow(SafeArrayUnaccessData(loadAlwaysList));
- }
-#endif // !FEATURE_CORECLR
public:
void GetOutputFolder();
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
void SetPlatformAssembliesPaths(LPCWSTR pwzPlatformAssembliesPaths);
void SetTrustedPlatformAssemblies(LPCWSTR pwzTrustedPlatformAssemblies);
void SetPlatformResourceRoots(LPCWSTR pwzPlatformResourceRoots);
void SetAppNiPaths(LPCWSTR pwzAppNiPaths);
void SetPlatformWinmdPaths(LPCWSTR pwzPlatformWinmdPaths);
void SetForceFullTrust(bool val);
-#endif // FEATURE_CORECLR || CROSSGEN_COMPILE
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
void SetCLRJITPath(LPCWSTR pwszCLRJITPath);
void SetDontLoadJit();
#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
-#if defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#if !defined(NO_NGENPDB)
void SetDiasymreaderPath(LPCWSTR pwzDiasymreaderPath);
#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
bool m_legacyMode; // true if the zapper was invoked using legacy mode
-#ifdef FEATURE_CORECLR
bool m_fNoMetaData; // Do not copy metadata and IL to native image
-#endif
ZapperOptions();
~ZapperOptions();
#include "ipcshared.h"
#include "ipcmanagerinterface.h"
-#ifndef FEATURE_CORECLR
-#include "AppXUtil.h"
-#endif
#if defined(FEATURE_IPCMAN)
return hr;
}
-#ifndef FEATURE_CORECLR
- // when pid != GetCurrentProcessId() it means we're the consumer opening other process perf counter data
- if (pid != GetCurrentProcessId())
- {
- // if the target process is inside an appcontainer we need to add the appcontainer SID to the boundary descriptor.
- NewArrayHolder<BYTE> pbTokenMem;
- hr = AppX::GetAppContainerTokenInfoForProcess(pid, pbTokenMem);
-
- if (FAILED(hr))
- {
- // failed to open the target's process, continue on
- // assuming that the process isn't in an AppContainer.
- _ASSERTE(pbTokenMem == NULL);
- }
- else
- {
- if (hr == S_FALSE)
- {
- // not an appcontainer
- _ASSERTE(pbTokenMem == NULL);
- }
- else
- {
- // process is an appcontainer so add the SID
- PTOKEN_APPCONTAINER_INFORMATION pAppContainerTokenInfo =
- reinterpret_cast<PTOKEN_APPCONTAINER_INFORMATION>(pbTokenMem.GetValue());
- _ASSERTE(pAppContainerTokenInfo);
- _ASSERTE(pAppContainerTokenInfo->TokenAppContainer);
-
- if (!(*pAddSIDToBoundaryDescriptor)(&pBoundaryDesc, pAppContainerTokenInfo->TokenAppContainer))
- return HRESULT_FROM_WIN32(GetLastError());
- }
- }
- }
-#endif // FEATURE_CORECLR
if(bCreate)
{
int iSIDforAdmin = -1;
int iSIDforUsers = -1;
int iSIDforLoggingUsers = -1;
-#if !defined (DACCESS_COMPILE) && !defined(FEATURE_CORECLR)
- NewArrayHolder<BYTE> pbTokenMem;
- PTOKEN_APPCONTAINER_INFORMATION pAppContainerTokenInfo = NULL;
-#endif
PermStruct[0].rgPSID = NULL;
// non-fatal error, so don't goto errorexit
}
-#if !defined(DACCESS_COMPILE) && !defined(FEATURE_CORECLR)
- // when running on win8 if the process is an appcontainer then add the appcontainer SID to the ACL
- // going down this code path means we're creating the descriptor for our current PID.
- _ASSERTE(pid == GetCurrentProcessId());
- hr = AppX::GetAppContainerTokenInfoForProcess(pid, pbTokenMem);
-
- if (FAILED(hr))
- {
- // failed to open the target's process, continue on
- // assuming that the process isn't in an AppContainer.
- _ASSERTE(pbTokenMem == NULL);
- }
- else
- {
- if (hr == S_FALSE)
- {
- // not an appcontainer
- _ASSERTE(pbTokenMem == NULL);
- }
- else
- {
- // process is an appcontainer so add the SID
- pAppContainerTokenInfo =
- reinterpret_cast<PTOKEN_APPCONTAINER_INFORMATION>(pbTokenMem.GetValue());
- _ASSERTE(pAppContainerTokenInfo);
- _ASSERTE(pAppContainerTokenInfo->TokenAppContainer);
-
- PermStruct[cActualACECount].rgPSID = pAppContainerTokenInfo->TokenAppContainer;
- PermStruct[cActualACECount].rgAccessFlags = GetAccessFlagsForObject(whatObject, FALSE);
- ++cActualACECount;
- }
- }
-#endif // !defined(DACCESS_COMPILE) && !defined(FEATURE_CORECLR)
}
_ASSERTE(cActualACECount <= MaxNumberACEs);
{
// pClsid szProgID pfnCreateObject
{ &CLSID_CorMetaDataDispenser, W("CorMetaDataDispenser"), Disp::CreateObject },
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE) // coreclr doesn't export these
- { &CLSID_CorMetaDataDispenserRuntime, W("CorMetaDataDispenserRuntime"), Disp::CreateObject },
-
- { &CLSID_CorRuntimeHost, W("CorRuntimeHost"), CorHost::CreateObject },
- { &CLSID_CLRRuntimeHost, W("CLRRuntimeHost"), CorHost2::CreateObject },
- { &__uuidof(CLRPrivRuntime), W("CLRPrivRuntime"), CorHost2::CreateObject },
- { &CLSID_TypeNameFactory, NULL, (PFN_CREATE_OBJ)TypeNameFactoryCreateObject },
-#endif // FEATURE_CORECLR && !CROSSGEN_COMPILE
{ NULL, NULL, NULL }
};
return hr;
} // Disp::OpenScopeOnMemory
-#if defined(FEATURE_METADATA_IN_VM) && !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-
-#include <metahost.h>
-// Pointer to the activated CLR interface provided by the shim.
-extern ICLRRuntimeInfo * g_pCLRRuntime;
-
-#endif
//*****************************************************************************
// Get the directory where the CLR system resides.
DWORD cchBuffer, // [in] Size of the buffer
DWORD *pcchBuffer) // [out] Number of characters returned
{
-#if defined(FEATURE_METADATA_IN_VM) && !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- // This implies a machine-wide CLR install root, which may not exist for some CLR
- // skus using standalone metadata.
- *pcchBuffer = cchBuffer;
- hr = g_pCLRRuntime->GetRuntimeDirectory(szBuffer, pcchBuffer);
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-#else //!FEATURE_METADATA_IN_VM || FEATURE_CORECLR
-#ifdef FEATURE_CORECLR
UNREACHABLE_MSG("Calling IMetaDataDispenser::GetCORSystemDirectory! This code should not be "
"reachable or needs to be reimplemented for CoreCLR!");
-#endif //FEATURE_CORECLR
return E_NOTIMPL;
-#endif //!FEATURE_METADATA_IN_VM || FEATURE_CORECLR
} // Disp::GetCORSystemDirectory
HRESULT Disp::FindAssembly( // S_OK or error
}
#endif //FEATURE_METADATA_EMIT
-#if defined(FEATURE_METADATA_IN_VM) && !defined(FEATURE_CORECLR)
- else if (riid == IID_IMetaDataValidate)
- {
- *ppUnk = (IMetaDataValidate *)this;
- }
-#endif //defined(FEATURE_METADATA_IN_VM) && !defined(FEATURE_CORECLR)
#ifdef FEATURE_METADATA_EMIT_ALL
else if (riid == IID_IMetaDataFilter)
CorValidatorModuleType m_ModuleType;
IVEHandler *m_pVEHandler;
-#ifndef FEATURE_CORECLR
- ValidateRecordFunction m_ValidateRecordFunctionTable[TBL_COUNT];
-#endif
CCustAttrHash m_caHash; // Hashed list of custom attribute types seen.
bool m_bKeepKnownCa; // Should all known CA's be kept?
#include <metamodelrw.h>
-#ifndef FEATURE_CORECLR
-
-#include <metahost.h>
-
-// Pointer to the activated CLR interface provided by the shim.
-extern ICLRRuntimeInfo *g_pCLRRuntime;
-
-#ifdef FEATURE_METADATA_EMIT_ALL
-
-#include "iappdomainsetup.h"
-
-// {27FFF232-A7A8-40dd-8D4A-734AD59FCD41}
-EXTERN_GUID(IID_IAppDomainSetup, 0x27FFF232, 0xA7A8, 0x40dd, 0x8D, 0x4A, 0x73, 0x4A, 0xD5, 0x9F, 0xCD, 0x41);
-
-#endif //FEATURE_METADATA_EMIT_ALL
-
-#endif // !FEATURE_CORECLR
#define DEFINE_CUSTOM_NODUPCHECK 1
//*****************************************************************************
HRESULT RegMeta::StartupEE()
{
-#ifdef FEATURE_CORECLR
UNREACHABLE_MSG_RET("About to CoCreateInstance! This code should not be "
"reachable or needs to be reimplemented for CoreCLR!");
-#else // !FEATURE_CORECLR
-
- struct Param
- {
- RegMeta *pThis;
- IUnknown *pSetup;
- IAppDomainSetup *pDomainSetup;
- bool fDoneStart;
- HRESULT hr;
- } param;
- param.pThis = this;
- param.pSetup = NULL;
- param.pDomainSetup = NULL;
- param.fDoneStart = false;
- param.hr = S_OK;
-
- PAL_TRY(Param *, pParam, ¶m)
- {
- HRESULT hr = S_OK;
-
- DWORD dwBuffer[1 + (MAX_LONGPATH+1) * sizeof(WCHAR) / sizeof(DWORD) + 1];
- BSTR bstrDir = NULL;
-
- // Create a hosting environment.
- IfFailGo(g_pCLRRuntime->GetInterface(
- CLSID_CorRuntimeHost,
- IID_ICorRuntimeHost,
- (void **)&pParam->pThis->m_pCorHost));
-
- // Startup the runtime.
- IfFailGo(pParam->pThis->m_pCorHost->Start());
- pParam->fDoneStart = true;
-
- // Create an AppDomain Setup so we can set the AppBase.
- IfFailGo(pParam->pThis->m_pCorHost->CreateDomainSetup(&pParam->pSetup));
-
- // Get the current directory (place it in a BSTR).
- bstrDir = (BSTR)(dwBuffer + 1);
- if ((dwBuffer[0] = (WszGetCurrentDirectory(MAX_LONGPATH + 1, bstrDir) * sizeof(WCHAR))))
- {
- // QI for the IAppDomainSetup interface.
- IfFailGo(pParam->pSetup->QueryInterface(IID_IAppDomainSetup,
- (void**)&pParam->pDomainSetup));
-
- // Set the AppBase.
- pParam->pDomainSetup->put_ApplicationBase(bstrDir);
- }
-
- // Create a new AppDomain.
- IfFailGo(pParam->pThis->m_pCorHost->CreateDomainEx(W("Compilation Domain"),
- pParam->pSetup,
- NULL,
- &pParam->pThis->m_pAppDomain));
-
- // That's it, we're all set up.
- _ASSERTE(pParam->pThis->m_pAppDomain != NULL);
- pParam->pThis->m_fStartedEE = true;
-
- ErrExit:
- pParam->hr = hr;
- }
- PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- _ASSERTE(!"Unexpected exception setting up hosting environment for security attributes");
- param.hr = E_FAIL;
- }
- PAL_ENDTRY
-
- // Cleanup temporary resources.
- if (m_pAppDomain && FAILED(param.hr))
- m_pAppDomain->Release();
- if (param.pDomainSetup)
- param.pDomainSetup->Release();
- if (param.pSetup)
- param.pSetup->Release();
- if (param.fDoneStart && FAILED(param.hr))
- m_pCorHost->Stop();
- if (m_pCorHost && FAILED(param.hr))
- m_pCorHost->Release();
- return param.hr;
-#endif // FEATURE_CORECLR
}
#endif //FEATURE_METADATA_EMIT_ALL
goto ErrExit;
}
-#ifndef FEATURE_CORECLR
- wcscpy_s(rcModule, _MAX_PATH, wzNameSpace);
-
- //******************
- // Try to find the module on CORPATH
- //******************
-
- if ((wcsncmp(rcModule, W("System."), 16) != 0) &&
- (wcsncmp(rcModule, W("System/"), 16) != 0))
- {
- // only go through regular CORPATH lookup by fully qualified class name when
- // it is not System.*
- hr = CORPATHService::GetClassFromCORPath(
- rcModule,
- tr,
- pMiniMd,
- riid,
- ppIScope,
- ptd);
- }
- else
- {
- // force it to look for System.* in mscorlib.dll
- hr = S_FALSE;
- }
-
- if (hr == S_FALSE)
- {
- LPWSTR szTmp;
- WszSearchPath(
- NULL,
- W("mscorlib.dll"),
- NULL,
- sizeof(rcModule) / sizeof(rcModule[0]),
- rcModule,
- &szTmp);
-
- //*******************
- // Last desperate try!!
- //*******************
-
- // Use the file name "mscorlib:
- IfFailGo(CORPATHService::FindTypeDef(
- rcModule,
- tr,
- pMiniMd,
- riid,
- ppIScope,
- ptd));
- if (hr == S_FALSE)
- {
- IfFailGo(META_E_CANNOTRESOLVETYPEREF);
- }
- }
-#else //FEATURE_CORECLR
IfFailGo(META_E_CANNOTRESOLVETYPEREF);
-#endif //FEATURE_CORECLR
ErrExit:
STOP_MD_PERF(ResolveTypeRef);
CLiteWeightStgdbRW::IsValidFileNameLength(
const WCHAR * wszFileName)
{
-#ifdef FEATURE_CORECLR
return TRUE;
-#else
- static const WCHAR const_wszLongPathPrefix[] = W("\\\\?\\");
-
- if (wszFileName == NULL)
- {
- return TRUE;
- }
- size_t cchFileName = wcslen(wszFileName);
- if (cchFileName < _MAX_PATH)
- {
- return TRUE;
- }
- if (SString::_wcsnicmp(wszFileName, const_wszLongPathPrefix, _countof(const_wszLongPathPrefix) - 1) != 0)
- { // Path does not have long path prefix \\?\ (as required by CreateFile API)
- return FALSE;
- }
- if (cchFileName < 32767)
- { // Limit for the long path length as defined in CreateFile API
- return TRUE;
- }
- return FALSE;
-#endif
} // CLiteWeightStgdbRW::IsValidFileNameLength
return E_INVALIDARG;
}
-#ifndef FEATURE_CORECLR
- // Verify that the delta is based on the base.
- IfFailGo(mdDelta.getEncBaseIdOfModule(pModDelta, &GuidDelta));
- IfFailGo(getEncBaseIdOfModule(pModBase,&GuidBase));
- if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_DeltaCheck) &&
- CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_UseMinimalDeltas) &&
- (GuidDelta != GuidBase))
- {
- _ASSERTE(!"The Delta MetaData is based on a different generation than the current MetaData.");
- return E_INVALIDARG;
- }
-#endif //!FEATURE_CORECLR
// Let the other md prepare for sparse records.
IfFailGo(mdDelta.StartENCMap());
HRESULT hrReturn = hr;
IfFailRet(mdDelta.EndENCMap());
-#ifndef FEATURE_CORECLR
- if (SUCCEEDED(hrReturn) &&
- CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_DeltaCheck) &&
- CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_UseMinimalDeltas))
- {
- GUID GuidNewBase;
-
- // We'll use the delta's 'delta guid' for our new base guid
- IfFailRet(mdDelta.getEncIdOfModule(pModDelta, &GuidNewBase));
-
- IfFailRet(PutGuid(TBL_Module, ModuleRec::COL_EncBaseId, pModBase, GuidNewBase));
- }
-#endif //!FEATURE_CORECLR
return hrReturn;
} // CMiniMdRW::ApplyDelta
// Get the module record.
IfFailGo(GetModuleRecord(1, &pMod));
-#ifndef FEATURE_CORECLR
- if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_UseMinimalDeltas))
- { // Update the ENC Guids
- GUID encid;
- // Copy EncId as BaseId.
- ULONG uVal = GetCol(TBL_Module, ModuleRec::COL_EncId, pMod);
- IfFailGo(PutCol(TBL_Module, ModuleRec::COL_EncBaseId, pMod, uVal));
-
- // Allocate a new GUID for EncId.
- IfFailGo(CoCreateGuid(&encid));
- IfFailGo(PutGuid(TBL_Module, ModuleRec::COL_EncId, pMod, encid));
- }
-#endif //!FEATURE_CORECLR
// Reset the pool deltas
m_StringHeap.StartNewEnCSession();
void EnableDeltaMetadataGeneration()
{
_ASSERTE(m_OptionValue.m_UpdateMode == MDUpdateENC);
-#ifndef FEATURE_CORECLR
- if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_UseMinimalDeltas))
- m_OptionValue.m_UpdateMode = MDUpdateDelta;
-#endif //!FEATURE_CORECLR
}
void DisableDeltaMetadataGeneration() {m_OptionValue.m_UpdateMode = MDUpdateENC;}
,int line
#endif //_DEBUG
);
-#if defined(FEATURE_METADATA_IN_VM) && !defined(FEATURE_CORECLR)
-#ifdef _DEBUG
-#define VerifyNotWinMD(pUnknown, assertMsg) VerifyNotWinMDHelper(pUnknown, assertMsg, __FILE__, __LINE__)
-#else
-#define VerifyNotWinMD(pUnknown, assertMsg) VerifyNotWinMDHelper(pUnknown)
-#endif
-#else
#define VerifyNotWinMD(pUnknown, assertMsg) S_OK
-#endif // FEATURE_METADATA_IN_VM
#endif //__WINMDINTERFACES_H__
if (ppPublicKeytoken)
{
-#ifdef FEATURE_CORECLR
if (index == FrameworkAssembly_Mscorlib)
{
*ppPublicKeytoken = g_rbTheSilverlightPlatformKeyToken;
*pTokenLength = sizeof(g_rbTheSilverlightPlatformKeyToken);
}
else
-#endif
{
if (index == FrameworkAssembly_SystemNumericsVectors || index == FrameworkAssembly_SystemRuntime || index == FrameworkAssembly_SystemObjectModel)
{
if (pusRevisionNumber != nullptr)
*pusRevisionNumber = VER_ASSEMBLYBUILD_QFE;
-#ifdef FEATURE_CORECLR
// Under CoreCLR, we replace the ECMA key in the mscorlib assembly ref with the CoreCLR platform public key token
if (ppbPublicKeyOrToken != nullptr)
{
*ppbPublicKeyOrToken = g_rbTheSilverlightPlatformKeyToken;
*pcbPublicKeyOrToken = _countof(g_rbTheSilverlightPlatformKeyToken);
}
-#endif
}
else if (RidFromToken(mdar) > m_rawAssemblyRefCount)
{
case FrameworkAssembly_SystemRuntimeWindowsRuntimeUIXaml:
return "System.Runtime.WindowsRuntime.UI.Xaml";
case FrameworkAssembly_SystemNumericsVectors:
-#ifdef FEATURE_CORECLR
return "System.Numerics.Vectors";
-#else
- return "System.Numerics";
-#endif
default:
_ASSERTE(!"Invalid AssemblyRef token!");
return NULL;
// 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.
-#if defined(SILVERLIGHT) || defined(FEATURE_CORECLR)
+#if defined(SILVERLIGHT)
#if defined(FEATURE_CORESYSTEM)
#define asm_rmj 4
#define asm_rmm 0
/* append mode file I/O is safer */
#define _PAL_APPEND_DBG_OUTPUT_
-#if defined(_PAL_APPEND_DBG_OUTPUT_)
static const char FOPEN_FLAGS[] = "at";
-#else
-static const char FOPEN_FLAGS[] = "wt";
-#endif
/* number of ENTRY nesting levels to indicate with a '.' */
#define MAX_NESTING 50
#ifndef _SNCORECLR_H
#define _SNCORECLR_H
-#if !defined(FEATURE_CORECLR)
-#error sncoreclr.h should only be used on CoreCLR builds
-#endif // !FEATURE_CORECLR
void InitUtilcode();
}
NEW_WRAPPER_TEMPLATE1(StrongNameBufferHolder, VoidStrongNameFreeBuffer<_TYPE>);
-#if !defined(FEATURE_CORECLR) || (defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX))
+#if defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX)
// Holder for HCRYPTPROV handles directly allocated from CAPI
inline void ReleaseCapiProvider(HCRYPTPROV hProv)
{
bool StrongNameIsTheKey(__in_ecount(cbKey) const BYTE *pbKey, DWORD cbKey);
-#if !defined(FEATURE_CORECLR) || (defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX))
+#if defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX)
// Verify the format of a public key blob
bool StrongNameIsValidKeyPair(__in_ecount(cbKeyPair) const BYTE *pbKeyPair, DWORD cbKeyPair);
bool StrongNameCryptAcquireContext(HCRYPTPROV *phProv, LPCWSTR pwszContainer, LPCWSTR pwszProvider, DWORD dwProvType, DWORD dwFlags);
#endif // !FEATURE_CORECLR || (CROSSGEN_COMPILE && !PLATFORM_UNIX)
-#ifdef FEATURE_CORECLR
bool StrongNameIsSilverlightPlatformKey(__in_ecount(cbKey) const BYTE *pbKey, DWORD cbKey);
bool StrongNameIsSilverlightPlatformKey(const PublicKeyBlob &keyPublicKey);
-#endif // FEATURE_CORECLR
#endif // !_STRONGNAME_INTERNAL_H
static const BYTE g_rbTheKeyToken[] = {0xb0,0x3f,0x5f,0x7f,0x11,0xd5,0x0a,0x3a};
-#ifdef FEATURE_CORECLR
static const BYTE g_rbTheSilverlightPlatformKey[] =
{
0x00,0x24,0x00,0x00,0x04,0x80,0x00,0x00,0x94,0x00,0x00,0x00,0x06,0x02,0x00,0x00,
#endif
// for FEATURE_WINDOWSPHONE, we can add the Microsoft.Phone key and the Xna key to the list of blessed keys...
-#endif // FEATURE_CORECLR
STDAPI CreatePDBWorker(LPCWSTR pwzAssemblyPath, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzAppNiPaths, LPCWSTR pwzPdbPath, BOOL fGeneratePDBLinesInfo, LPCWSTR pwzManagedPdbSearchPath, LPCWSTR pwzPlatformWinmdPaths, LPCWSTR pwzDiasymreaderPath);
STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzOutputFilename=NULL, LPCWSTR pwzPlatformWinmdPaths=NULL, ICorSvcLogger *pLogger = NULL, LPCWSTR pwszCLRJITPath = nullptr);
void SetSvcLogger(ICorSvcLogger *pCorSvcLogger);
-#ifdef FEATURE_CORECLR
void SetMscorlibPath(LPCWSTR wzSystemDirectory);
-#endif
/* --------------------------------------------------------------------------- *
* Console stuff
void PrintLogoHelper()
{
-#ifdef FEATURE_CORECLR
Output(W("Microsoft (R) CoreCLR Native Image "));
-#else
- Output(W("Microsoft (R) CLR Native Image "));
-#endif
Outputf(W("Generator - Version %S\n"), VER_FILEVERSION_STR);
Outputf(W("%S\n"), VER_LEGALCOPYRIGHT_LOGO_STR);
Output(W("\n"));
W(" /nologo - Prevents displaying the logo\n")
W(" @response.rsp - Process command line arguments from specified\n")
W(" response file\n")
-#ifdef FEATURE_CORECLR
W(" /partialtrust - Assembly will be run in a partial trust domain.\n")
-#endif
W(" /in <file> - Specifies input filename (optional)\n")
W(" /out <file> - Specifies output filename (optional)\n")
-#ifdef FEATURE_CORECLR
W(" /Trusted_Platform_Assemblies <path[") PATH_SEPARATOR_STR_W W("path]>\n")
W(" - List of assemblies treated as trusted platform\n")
W(" - Cannot be used with Platform_Assemblies_Paths\n")
W(" - List of paths containing user-application native images\n")
W(" - Must be used with /CreatePDB switch\n")
#endif // NO_NGENPDB
-#endif // FEATURE_CORECLR
W(" /Platform_Assemblies_Paths <path[") PATH_SEPARATOR_STR_W W("path]>\n")
W(" - List of paths containing target platform assemblies\n")
-#ifdef FEATURE_CORECLR
// If Platform_Assemblies_Paths, we will use it to build the TPA list and thus,
// TPA list cannot be explicitly specified.
W(" - Cannot be used with Trusted_Platform_Assemblies\n")
-#endif // FEATURE_CORECLR
#ifdef FEATURE_COMINTEROP
W(" /Platform_Winmd_Paths <path[") PATH_SEPARATOR_STR_W W("path]>\n")
W(" /Tuning - Generate an instrumented image to collect\n")
W(" scenario traces, which can be used with ibcmerge.exe\n")
#endif
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
W(" /JITPath <path>\n")
W(" - Specifies the absolute file path to JIT compiler to be used.\n")
#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
W(" WinMD Parameters\n")
W(" /WinMDResilient - Generate images resilient to WinMD dependency changes.\n")
#endif
-#ifdef FEATURE_CORECLR
W(" Size on Disk Parameters\n")
W(" /NoMetaData - Do not copy metadata and IL into native image.\n")
-#endif // FEATURE_CORECLR
#ifndef NO_NGENPDB
W(" Debugging Parameters\n")
W(" /CreatePDB <Dir to store PDB> [/lines [<search path for managed PDB>] ]\n")
W(" When specifying /CreatePDB, the native image should be created\n")
W(" first, and <assembly name> should be the path to the NI.\n")
-#ifdef FEATURE_CORECLR
W(" /DiasymreaderPath <Path to diasymreader.dll>\n")
W(" - Specifies the absolute file path to diasymreader.dll to be used.\n")
-#endif // FEATURE_CORECLR
#elif defined(FEATURE_PERFMAP)
W(" Debugging Parameters\n")
W(" /CreatePerfMap <Dir to store perf map>\n")
return !_wcsicmp(pwzStringEnd, pwzCandidate);
}
-#ifdef FEATURE_CORECLR
//
// When using the Phone binding model (TrustedPlatformAssemblies), automatically
// detect which path CoreLib.[ni.]dll lies in.
}
}
}
-#endif // FEATURE_CORECLR
extern HMODULE g_hThisInst;
LPCWSTR pwzOutputFilename = NULL;
LPCWSTR pwzPublicKeys = nullptr;
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
LPCWSTR pwszCLRJITPath = nullptr;
#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
// By default, Crossgen will assume code-generation for fulltrust domains unless /PartialTrust switch is specified
dwFlags |= NGENWORKER_FLAGS_FULLTRUSTDOMAIN;
-#ifdef FEATURE_CORECLR
// By default, Crossgen will generate readytorun images unless /FragileNonVersionable switch is specified
dwFlags |= NGENWORKER_FLAGS_READYTORUN;
-#endif
while (argc > 0)
{
{
dwFlags |= NGENWORKER_FLAGS_MISSINGDEPENDENCIESOK;
}
-#ifdef FEATURE_CORECLR
else if (MatchParameter(*argv, W("PartialTrust")))
{
// Clear the /fulltrust flag
argc--;
}
#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE)
-#endif
#ifdef FEATURE_WINMD_RESILIENT
else if (MatchParameter(*argv, W("WinMDResilient")))
{
dwFlags &= ~NGENWORKER_FLAGS_READYTORUN;
}
#endif
-#ifdef FEATURE_CORECLR
else if (MatchParameter(*argv, W("NoMetaData")))
{
dwFlags |= NGENWORKER_FLAGS_NO_METADATA;
}
-#endif
else if (MatchParameter(*argv, W("out")))
{
if (pwzOutputFilename != NULL)
argv++;
argc--;
}
-#ifdef FEATURE_CORECLR
else if (MatchParameter(*argv, W("Trusted_Platform_Assemblies")) && (argc > 1))
{
pwzTrustedPlatformAssemblies = argv[1];
argc--;
}
#endif // NO_NGENPDB
-#endif // FEATURE_CORECLR
else if (MatchParameter(*argv, W("Platform_Assemblies_Paths")) && (argc > 1))
{
pwzPlatformAssembliesPaths = argv[1];
argv--;
argc++;
}
-#ifdef FEATURE_CORECLR
else if (MatchParameter(*argv, W("DiasymreaderPath")) && (argc > 1))
{
pwzDiasymreaderPath = argv[1];
argv++;
argc--;
}
-#endif // FEATURE_CORECLR
#endif // NO_NGENPDB
#ifdef FEATURE_PERFMAP
else if (MatchParameter(*argv, W("CreatePerfMap")) && (argc > 1))
exit(FAILURE_RESULT);
}
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
if (pwszCLRJITPath != nullptr && fCreatePDB)
{
Output(W("The /JITPath switch can not be used with the /CreatePDB switch.\n"));
}
#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
-#if defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#if !defined(NO_NGENPDB)
if (pwzDiasymreaderPath != nullptr && !fCreatePDB)
{
Output(W("The /DiasymreaderPath switch can only be used with the /CreatePDB switch.\n"));
}
#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
-#if defined(FEATURE_CORECLR)
if ((pwzTrustedPlatformAssemblies != nullptr) && (pwzPlatformAssembliesPaths != nullptr))
{
Output(W("The /Trusted_Platform_Assemblies and /Platform_Assemblies_Paths switches cannot be both specified.\n"));
exit(FAILURE_RESULT);
}
}
-#endif // FEATURE_CORESYSTEM
#ifdef FEATURE_READYTORUN_COMPILER
if (((dwFlags & NGENWORKER_FLAGS_TUNING) != 0) && ((dwFlags & NGENWORKER_FLAGS_READYTORUN) != 0))
PathString wzTrustedPathRoot;
-#ifdef FEATURE_CORECLR
SString ssTPAList;
if (fCreatePDB)
SetMscorlibPath(pwzPlatformAssembliesPaths);
}
}
-#endif // FEATURE_CORECLR
if (pwzPlatformAssembliesPaths == NULL)
{
pwzAppPaths,
pwzOutputFilename,
pwzPlatformWinmdPaths
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
,
NULL, // ICorSvcLogger
pwszCLRJITPath
#define LEGACY_ACTIVATION_SHIM_LOAD_LIBRARY WszLoadLibrary
#define LEGACY_ACTIVATION_SHIM_DEFINE_CoInitializeEE
-#ifndef FEATURE_CORECLR
-#include "LegacyActivationShim.h"
-#endif
#define ENUM_BUFFER_SIZE 10
#define TAB_SIZE 8
pIErr->Release();
}
-#ifndef FEATURE_CORECLR
- LegacyActivationShim::CoUninitializeCor();
-#ifndef FEATURE_PAL
- CoUninitialize();
-#endif
-#endif
exit(hr);
} // void MDInfo::Error()
#include "shlwapi.h" // Path manipulation APIs
-#ifdef FEATURE_CORECLR
GVAL_IMPL(bool, g_fAppX);
INDEBUG(bool g_fIsAppXAsked;)
#endif
};
-#else // FEATURE_CORECLR
-
-//---------------------------------------------------------------------------------------------
-// Convenience values
-
-#ifndef E_INSUFFICIENT_BUFFER
- #define E_INSUFFICIENT_BUFFER (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
-#endif
-
-#ifndef E_FILE_NOT_FOUND
- #define E_FILE_NOT_FOUND (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
-#endif
-
-//---------------------------------------------------------------------------------------------
-using clr::str::IsNullOrEmpty;
-
-//---------------------------------------------------------------------------------------------
-typedef decltype(GetCurrentPackageId) GetCurrentPackageId_t;
-typedef decltype(GetCurrentPackageInfo) GetCurrentPackageInfo_t;
-typedef decltype(GetCurrentPackagePath) GetCurrentPackagePath_t;
-typedef decltype(OpenPackageInfoByFullName) OpenPackageInfoByFullName_t;
-typedef decltype(ClosePackageInfo) ClosePackageInfo_t;
-typedef decltype(GetPackageInfo) GetPackageInfo_t;
-
-//---------------------------------------------------------------------------------------------
-// Caches AppX ARI API-related information.
-struct AppXRTInfo
-{
- HMODULE m_hAppXRTMod;
- bool m_fIsAppXProcess;
- bool m_fIsAppXAdaptiveApp;
- bool m_fIsAppXNGen;
-
- GetCurrentPackageId_t * m_pfnGetCurrentPackageId;
- GetCurrentPackageInfo_t * m_pfnGetCurrentPackageInfo;
- GetCurrentPackagePath_t * m_pfnGetCurrentPackagePath;
-
- NewArrayHolder<BYTE> m_pbAppContainerInfo;
- DWORD m_cbAppContainerInfo;
-
- struct CurrentPackageInfo
- {
- UINT32 m_cbCurrentPackageInfo;
- PBYTE m_pbCurrentPackageInfo;
- UINT32 m_nCount;
-
- CurrentPackageInfo(UINT32 cbPkgInfo, PBYTE pbPkgInfo, UINT32 nCount)
- : m_cbCurrentPackageInfo(cbPkgInfo)
- , m_pbCurrentPackageInfo(pbPkgInfo)
- , m_nCount(nCount)
- { LIMITED_METHOD_CONTRACT; }
-
- ~CurrentPackageInfo()
- {
- LIMITED_METHOD_CONTRACT;
- if (m_pbCurrentPackageInfo != nullptr)
- {
- delete [] m_pbCurrentPackageInfo;
- m_pbCurrentPackageInfo = nullptr;
- }
- }
- };
-
- CurrentPackageInfo * m_pCurrentPackageInfo;
-
- NewArrayHolder<WCHAR> m_AdaptiveAppWinmetadataDir;
-
- AppXRTInfo() :
- m_hAppXRTMod(nullptr),
- m_fIsAppXProcess(false),
- m_fIsAppXAdaptiveApp(false),
- m_fIsAppXNGen(false),
- m_pfnGetCurrentPackageId(nullptr),
- m_pfnGetCurrentPackageInfo(nullptr),
- m_pfnGetCurrentPackagePath(nullptr),
- m_pbAppContainerInfo(nullptr),
- m_pCurrentPackageInfo(nullptr),
- m_AdaptiveAppWinmetadataDir(nullptr)
- { LIMITED_METHOD_CONTRACT; }
-
- ~AppXRTInfo()
- {
- LIMITED_METHOD_CONTRACT;
- if (m_pCurrentPackageInfo != nullptr)
- {
- delete m_pCurrentPackageInfo;
- m_pCurrentPackageInfo = nullptr;
- }
-
- if (m_hAppXRTMod != nullptr)
- {
- FreeLibrary(m_hAppXRTMod);
- m_hAppXRTMod = nullptr;
- }
- }
-}; // struct AppXRTInfo
-
-GPTR_IMPL(AppXRTInfo, g_pAppXRTInfo); // Relies on zero init static memory.
-
-#ifndef DACCESS_COMPILE
-
-//---------------------------------------------------------------------------------------------
-static
-HRESULT GetAppContainerTokenInfoForProcess(
- DWORD pid,
- NewArrayHolder<BYTE>& pbAppContainerTokenInfo,
- DWORD* pcbAppContainerTokenInfo)
-{
- PRECONDITION(CheckPointer(pcbAppContainerTokenInfo, NULL_OK));
-
- HRESULT hr = S_OK;
-
- pbAppContainerTokenInfo = nullptr;
-
- // In order to get the AppContainer SID we need to open the process token
- HandleHolder hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
- if (hProcess == NULL)
- return HRESULT_FROM_GetLastError();
-
- HandleHolder hToken;
- if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken))
- return HRESULT_FROM_GetLastError();
-
- // Query the process to see if it's inside an AppContainer
- ULONG isAppContainer = 0;
- DWORD actualLength = 0;
- if (!GetTokenInformation(hToken, static_cast<TOKEN_INFORMATION_CLASS>(TokenIsAppContainer), &isAppContainer, sizeof(isAppContainer), &actualLength))
- return HRESULT_FROM_GetLastError();
-
- _ASSERTE(actualLength > 0);
-
- // Not an AppContainer so bail
- if (!isAppContainer)
- {
- return S_FALSE;
- }
-
- // Now we need the AppContainer SID so first get the required buffer length
- actualLength = 0;
- VERIFY(!GetTokenInformation(hToken, static_cast<TOKEN_INFORMATION_CLASS>(TokenAppContainerSid), NULL, 0, &actualLength));
- hr = HRESULT_FROM_GetLastError();
- _ASSERTE(hr == E_INSUFFICIENT_BUFFER);
-
- // Something unexpected happened
- if (hr != E_INSUFFICIENT_BUFFER)
- return hr;
-
- // Now we know the length of the AppContainer SID so create a buffer and retrieve it
- pbAppContainerTokenInfo = new (nothrow) BYTE[actualLength];
- IfNullRet(pbAppContainerTokenInfo);
-
- if (!GetTokenInformation(hToken, static_cast<TOKEN_INFORMATION_CLASS>(TokenAppContainerSid), pbAppContainerTokenInfo.GetValue(), actualLength, &actualLength))
- return HRESULT_FROM_GetLastError();
-
- if (pcbAppContainerTokenInfo != nullptr)
- *pcbAppContainerTokenInfo = actualLength;
-
- return S_OK;
-}
-
-//---------------------------------------------------------------------------------------------
-// Initializes a global AppXRTInfo structure if it has not already been initialized. Returns
-// false only in the event of OOM; otherwise caches the result of ARI information in
-// g_pAppXRTInfo. Thread safe.
-static
-HRESULT InitAppXRT()
-{
- // This will be used for catastrophic errors.
- HRESULT hr = S_OK;
-
- if (VolatileLoad(&g_pAppXRTInfo) == nullptr)
- {
- NewHolder<AppXRTInfo> pAppXRTInfo = new (nothrow) AppXRTInfo();
- IfNullRet(pAppXRTInfo); // Catastrophic error.
-
- pAppXRTInfo->m_fIsAppXProcess = false;
-
- do
- {
- if (!RunningOnWin8())
- {
- break;
- }
-
- LPCWSTR wzAppXRTDll = W("api-ms-win-appmodel-runtime-l1-1-0.dll");
- // Does not use GetLoadWithAlteredSearchPathFlag() because that would cause infinite recursion.
- pAppXRTInfo->m_hAppXRTMod = WszLoadLibraryEx(wzAppXRTDll, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
- if (pAppXRTInfo->m_hAppXRTMod == nullptr)
- { // Error is catastrophic: can't find kernel32.dll?
- hr = HRESULT_FROM_GetLastError();
- break;
- }
-
- pAppXRTInfo->m_pfnGetCurrentPackageId = reinterpret_cast<GetCurrentPackageId_t *>(
- GetProcAddress(pAppXRTInfo->m_hAppXRTMod, "GetCurrentPackageId"));
- if (pAppXRTInfo->m_pfnGetCurrentPackageId == nullptr)
- { // Error is non-catastrophic: could be running downlevel
- break;
- }
-
- pAppXRTInfo->m_pfnGetCurrentPackageInfo = reinterpret_cast<GetCurrentPackageInfo_t *>(
- GetProcAddress(pAppXRTInfo->m_hAppXRTMod, "GetCurrentPackageInfo"));
- if (pAppXRTInfo->m_pfnGetCurrentPackageInfo == nullptr)
- { // Error is catastrophic: GetCurrentPackageId is available but not GetCurrentPackageInfo?
- hr = HRESULT_FROM_GetLastError();
- break;
- }
-
- pAppXRTInfo->m_pfnGetCurrentPackagePath = reinterpret_cast<GetCurrentPackagePath_t *>(
- GetProcAddress(pAppXRTInfo->m_hAppXRTMod, "GetCurrentPackagePath"));
- if (pAppXRTInfo->m_pfnGetCurrentPackagePath == nullptr)
- { // Error is catastrophic: GetCurrentPackageInfo is available but not GetCurrentPackagePath?
- hr = HRESULT_FROM_GetLastError();
- break;
- }
-
- // Determine if this is an AppX process
- UINT32 cbBuffer = 0;
- LONG lRes = (*pAppXRTInfo->m_pfnGetCurrentPackageId)(&cbBuffer, nullptr);
- pAppXRTInfo->m_fIsAppXProcess = (lRes == ERROR_INSUFFICIENT_BUFFER);
-
- _ASSERTE(AppX::IsAppXSupported());
-
- hr = GetAppContainerTokenInfoForProcess(
- GetCurrentProcessId(),
- pAppXRTInfo->m_pbAppContainerInfo,
- &pAppXRTInfo->m_cbAppContainerInfo);
-
- if (FAILED(hr))
- {
- if (pAppXRTInfo->m_fIsAppXProcess)
- { // Error is catastrophic: running in true immersive process but no token info?
- }
- else
- { // Error is non-catastrophic: reset HRESULT to S_OK.
- hr = S_OK;
- }
- break;
- }
- }
- while (false);
-
- if (InterlockedCompareExchangeT<AppXRTInfo>(&g_pAppXRTInfo, pAppXRTInfo, nullptr) == nullptr)
- {
- pAppXRTInfo.SuppressRelease();
- }
- }
-
- return hr;
-}
-
-//---------------------------------------------------------------------------------------------
-// Inline helper to check first an only init when required.
-static inline HRESULT CheckInitAppXRT()
-{
- return (VolatileLoad(&g_pAppXRTInfo) != nullptr) ? S_OK : InitAppXRT();
-}
-
-#endif // !DACCESS_COMPILE
-
-//---------------------------------------------------------------------------------------------
-// Contains general helper methods for interacting with AppX functionality. This code will
-// gracefully fail on downlevel OS by returning false from AppX::IsAppXProcess, so always
-// call this API first to check before calling any of the others defined in this namespace.
-//
-// See http://windows/windows8/docs/Windows%208%20Feature%20Documents/Developer%20Experience%20(DEVX)/Apps%20Experience%20(APPX)/Modern%20Client/App%20Runtime%20Improvements%20API%20Developer%20Platform%20Spec.docm
-// for more information.
-
-namespace AppX
-{
-#ifdef DACCESS_COMPILE
-
- //-----------------------------------------------------------------------------------------
- // DAC-only IsAppXProcess. Returns false if g_pAppXRTInfo has not been initialized.
- bool DacIsAppXProcess()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return (g_pAppXRTInfo != nullptr && g_pAppXRTInfo->m_fIsAppXProcess);
- }
-
-#else // DACCESS_COMPILE
-
- //---------------------------------------------------------------------------------------------
- // cleans up resources allocated in InitAppXRT()
- void ShutDown()
- {
- if (VolatileLoad(&g_pAppXRTInfo) != nullptr)
- {
- delete g_pAppXRTInfo;
- g_pAppXRTInfo = nullptr;
- }
- }
-
- //-----------------------------------------------------------------------------------------
- // Returns true if the current process is immersive.
- // NOTE: a return value of true doesn't necessarily indicate that the process is a
- // real Metro app, e.g. it could be an ngen process compiling an AppX assembly.
- bool IsAppXProcess()
- {
- LIMITED_METHOD_CONTRACT;
- HRESULT hr = S_OK;
-
- if (FAILED(hr = CheckInitAppXRT()))
- {
- SetLastError(hr); // HRESULT_FROM_WIN32 is idempotent when error value is HRESULT.
- return false;
- }
-
- return g_pAppXRTInfo->m_fIsAppXProcess;
- }
-
- //-----------------------------------------------------------------------------------------
- // Returns true if the current process is immersive.
- // Only produces reliable results after IsAppXProcess is inititalized
- bool IsAppXProcess_Initialized_NoFault()
- {
- LIMITED_METHOD_CONTRACT;
- if (VolatileLoad(&g_pAppXRTInfo) == nullptr)
- {
- return false;
- }
- return g_pAppXRTInfo->m_fIsAppXProcess;
- }
-
- bool IsAppXNGen()
- {
- LIMITED_METHOD_CONTRACT;
- return VolatileLoad(&g_pAppXRTInfo) != nullptr && g_pAppXRTInfo->m_fIsAppXNGen;
- }
-
- //-----------------------------------------------------------------------------------------
- HRESULT InitCurrentPackageInfoCache()
- {
- LIMITED_METHOD_CONTRACT;
- HRESULT hr = S_OK;
-
- UINT32 cbBuffer = 0;
- hr = HRESULT_FROM_WIN32((*g_pAppXRTInfo->m_pfnGetCurrentPackageInfo)(PACKAGE_FILTER_CLR_DEFAULT, &cbBuffer, nullptr, nullptr));
- if (hr != E_INSUFFICIENT_BUFFER)
- return hr;
-
- NewArrayHolder<BYTE> pbBuffer(new (nothrow) BYTE[cbBuffer]);
- IfNullRet(pbBuffer);
-
- UINT32 nCount = 0;
- IfFailRet(HRESULT_FROM_WIN32((*g_pAppXRTInfo->m_pfnGetCurrentPackageInfo)(PACKAGE_FILTER_CLR_DEFAULT, &cbBuffer, pbBuffer, &nCount)));
-
- NewHolder<AppXRTInfo::CurrentPackageInfo> pPkgInfo(
- new (nothrow) AppXRTInfo::CurrentPackageInfo(cbBuffer, pbBuffer.Extract(), nCount));
- IfNullRet(pPkgInfo);
-
- if (InterlockedCompareExchangeT<AppXRTInfo::CurrentPackageInfo>(
- &g_pAppXRTInfo->m_pCurrentPackageInfo, pPkgInfo, nullptr) == nullptr)
- {
- pPkgInfo.SuppressRelease();
- }
-
- return S_OK;
- }
-
- //-----------------------------------------------------------------------------------------
- FORCEINLINE HRESULT CheckInitCurrentPackageInfoCache()
- {
- WRAPPER_NO_CONTRACT;
- PRECONDITION(IsAppXProcess());
-
- if (!IsAppXProcess())
- return E_UNEXPECTED;
-
- if (g_pAppXRTInfo->m_pCurrentPackageInfo == nullptr)
- return InitCurrentPackageInfoCache();
- else
- return S_OK;
- }
-
- //-----------------------------------------------------------------------------------------
- LPCWSTR GetHeadPackageMoniker()
- {
- STANDARD_VM_CONTRACT;
-
- IfFailThrow(CheckInitCurrentPackageInfoCache());
- return reinterpret_cast<PPACKAGE_INFO>(
- g_pAppXRTInfo->m_pCurrentPackageInfo->m_pbCurrentPackageInfo)->packageFullName;
- }
-
- //-----------------------------------------------------------------------------------------
- // Returns the current process' PACKAGE_ID in the provided buffer. See the ARI spec (above)
- // for more information.
- HRESULT GetCurrentPackageId(
- PUINT32 pBufferLength,
- PBYTE pBuffer)
- {
- LIMITED_METHOD_CONTRACT;
- HRESULT hr = S_OK;
-
- IfFailRet(CheckInitAppXRT());
- IfFailRet(HRESULT_FROM_WIN32((*g_pAppXRTInfo->m_pfnGetCurrentPackageId)(pBufferLength, pBuffer)));
-
- return S_OK;
- }
-
- //-----------------------------------------------------------------------------------------
- // Returns the current process' PACKAGE_INFO in the provided buffer. See the ARI spec
- // (above) for more information.
- HRESULT GetCurrentPackageInfo(
- UINT32 uiFlags,
- PUINT32 pcbBuffer,
- PBYTE pbBuffer,
- PUINT32 pnCount)
- {
- LIMITED_METHOD_CONTRACT;
- PRECONDITION(IsAppXProcess());
- PRECONDITION(CheckPointer(pcbBuffer));
-
- HRESULT hr = S_OK;
-
- IfFailRet(CheckInitAppXRT());
-
- if (pcbBuffer == nullptr)
- return E_INVALIDARG;
-
- if (uiFlags == PACKAGE_FILTER_CLR_DEFAULT)
- {
- IfFailRet(CheckInitCurrentPackageInfoCache());
-
- DWORD cbBuffer = *pcbBuffer;
- *pcbBuffer = g_pAppXRTInfo->m_pCurrentPackageInfo->m_cbCurrentPackageInfo;
- if (pnCount != nullptr)
- {
- *pnCount = g_pAppXRTInfo->m_pCurrentPackageInfo->m_nCount;
- }
-
- if (pbBuffer == nullptr || cbBuffer < g_pAppXRTInfo->m_pCurrentPackageInfo->m_cbCurrentPackageInfo)
- {
- return E_INSUFFICIENT_BUFFER;
- }
- memcpy(pbBuffer, g_pAppXRTInfo->m_pCurrentPackageInfo->m_pbCurrentPackageInfo, g_pAppXRTInfo->m_pCurrentPackageInfo->m_cbCurrentPackageInfo);
- }
- else
- {
- IfFailRet(HRESULT_FROM_WIN32((*g_pAppXRTInfo->m_pfnGetCurrentPackageInfo)(uiFlags, pcbBuffer, pbBuffer, pnCount)));
- }
-
- return S_OK;
- }
-
- //-----------------------------------------------------------------------------------------
- bool IsAdaptiveApp()
- {
- LIMITED_METHOD_CONTRACT;
-
- HRESULT hr = S_OK;
- static bool cachedIsAdaptiveApp = false;
-
- if (!IsAppXProcess())
- {
- return false;
- }
-
- if (!cachedIsAdaptiveApp)
- {
- cachedIsAdaptiveApp = true;
- LPWSTR adaptiveAppWinmetaDataDir = NULL;
-
- if (SUCCEEDED(hr = AppX::GetWinMetadataDirForAdaptiveApps(&adaptiveAppWinmetaDataDir)))
- {
- g_pAppXRTInfo->m_fIsAppXAdaptiveApp = clr::fs::Dir::Exists(adaptiveAppWinmetaDataDir);
-
- }
- else
- {
- SetLastError(hr);
- g_pAppXRTInfo->m_fIsAppXAdaptiveApp = false;
- }
-
- }
-
- return g_pAppXRTInfo->m_fIsAppXAdaptiveApp;
- }
-
-
- //-----------------------------------------------------------------------------------------
- // length : Upon success, contains the the length of packagePath
- // [in/out]
- //
- // packageRoot : Upon success, contains the full packagePath
- // [out] [ Note: The memory has to be preallocated for the above length]
- //
- HRESULT GetCurrentPackagePath(_Inout_ UINT32* length, _Out_opt_ PWSTR packageRoot)
- {
- PRECONDITION(IsAppXProcess());
- PRECONDITION(CheckPointer(length));
-
- HRESULT hr;
- IfFailRet(CheckInitAppXRT());
-
- IfFailRet(HRESULT_FROM_WIN32((*g_pAppXRTInfo->m_pfnGetCurrentPackagePath)(length, packageRoot)));
- return S_OK;
- }
-
- //-----------------------------------------------------------------------------------------
- // winMetadDataDir : Upon success, contains the absolute path for the winmetadata directory for the adaptive app
- // [out] NOTE: The string the pointer points to is global memory and never should be modified
- //
- HRESULT GetWinMetadataDirForAdaptiveApps(_Out_ LPWSTR* winMetadDataDir)
- {
-
- PRECONDITION(IsAppXProcess());
-
- HRESULT hr;
-
- IfFailRet(CheckInitAppXRT());
-
- if (g_pAppXRTInfo->m_AdaptiveAppWinmetadataDir == nullptr)
- {
- LPCWSTR wzWinMetadataFolder=W("\\WinMetadata");
- NewArrayHolder<WCHAR> wzCompletePath;
- UINT32 length=0;
-
- hr = GetCurrentPackagePath(&length, NULL);
- if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- return hr;
-
- NewArrayHolder<WCHAR> wzPath_holder = new (nothrow) WCHAR[length];
-
- IfNullRet(wzPath_holder);
- IfFailRet(GetCurrentPackagePath(&length, wzPath_holder.GetValue()));
-
- DWORD cchFullPathBuf = length + (DWORD)wcslen(wzWinMetadataFolder) + 1;
- IfNullRet(wzCompletePath = new (nothrow) WCHAR[cchFullPathBuf]);
- IfFailRet(clr::fs::Path::Combine(wzPath_holder.GetValue(), wzWinMetadataFolder, &cchFullPathBuf, wzCompletePath.GetValue()));
- g_pAppXRTInfo->m_AdaptiveAppWinmetadataDir = wzCompletePath.Extract();
- }
-
- *winMetadDataDir = g_pAppXRTInfo->m_AdaptiveAppWinmetadataDir;
-
- return S_OK;
- }
-
-#if defined(FEATURE_APPX_BINDER)
- //-----------------------------------------------------------------------------------------
- // Iterates the current process' packages and returns the first package that contains a
- // file matching wzFileName.
- //
- // wzFileName : The file to look for in the current process' packages. If this is a
- // [in] relative path, then it appends the path to the root of each package in
- // sequence to see if the resulting path points to an existing file. If this
- // is an absolute path, then for each package it determines if the package
- // root is a prefix of wzFileName.
- // pcchPathName : Upon entry contains the length of the buffer pwzPathName, and upon return
- // [in/out] contains either the number of characters written or the buffer size
- // required.
- // pwzPathName : Upon success, contains the absolute path for the first matching file.
- // [out]
- HRESULT FindFileInCurrentPackage(
- PCWSTR wzFileName,
- PUINT32 pcchPathName,
- PWSTR pwzPathName,
- UINT32 uiFlags,
- __in PCWSTR *rgwzAltPaths,
- __in UINT32 cAltPaths,
- FindFindInPackageFlags findInCurrentPackageFlags)
- {
- LIMITED_METHOD_CONTRACT;
- PRECONDITION(IsAppXProcess());
- PRECONDITION(CheckPointer(wzFileName));
- PRECONDITION(CheckPointer(pcchPathName));
- PRECONDITION(CheckPointer(pwzPathName));
-
- HRESULT hr = S_OK;
-
- if (!IsAppXProcess())
- return E_UNEXPECTED;
-
- // PACKAGE_FILTER_ALL_LOADED is obsolete, and shouldn't be used.
- // We also don't currently handle the case where PACKAGE_FILTER_HEAD isn't set.
- _ASSERTE(uiFlags != PACKAGE_FILTER_ALL_LOADED && (uiFlags & PACKAGE_FILTER_HEAD) != 0);
- if (uiFlags == PACKAGE_FILTER_ALL_LOADED || (uiFlags & PACKAGE_FILTER_HEAD) == 0)
- return E_NOTIMPL;
-
- // File name must be non-null and relative
- if (IsNullOrEmpty(wzFileName) || pcchPathName == nullptr || pwzPathName == nullptr)
- return E_INVALIDARG;
-
- // If we've been provided a full path and the file doesn't actually exist
- // then we can immediately say that this function will fail with "file not found".
- bool fIsRelative = clr::fs::Path::IsRelative(wzFileName);
- if (!fIsRelative && !clr::fs::File::Exists(wzFileName))
- return E_FILE_NOT_FOUND;
-
- IfFailRet(CheckInitCurrentPackageInfoCache());
-
- DWORD const cchFileName = static_cast<DWORD>(wcslen(wzFileName));
- DWORD cchFullPathBuf = _MAX_PATH;
- NewArrayHolder<WCHAR> wzFullPathBuf = new (nothrow) WCHAR[cchFullPathBuf];
- IfNullRet(wzFullPathBuf);
-
- auto FindFileInCurrentPackageHelper = [&](LPCWSTR wzPath) -> HRESULT
- {
- HRESULT hr = S_OK;
-
- if (!(findInCurrentPackageFlags & FindFindInPackageFlags_AllowLongFormatPath) && clr::fs::Path::HasLongFormatPrefix(wzPath))
- return COR_E_BAD_PATHNAME; // We can't handle long format paths.
-
- // If the path is relative, concatenate the package root and the file name and see
- // if the file exists.
- if (fIsRelative)
- {
- DWORD cchFullPath = cchFullPathBuf;
- hr = clr::fs::Path::Combine(wzPath, wzFileName, &cchFullPath, wzFullPathBuf);
- if (hr == E_INSUFFICIENT_BUFFER)
- {
- IfNullRet(wzFullPathBuf = new (nothrow) WCHAR[cchFullPathBuf = (cchFullPath + 1)]);
- hr = clr::fs::Path::Combine(wzPath, wzFileName, &cchFullPath, wzFullPathBuf);
- }
- IfFailRet(hr);
-
- if (!clr::fs::Path::IsValid(wzFullPathBuf, cchFullPath, !!(findInCurrentPackageFlags & FindFindInPackageFlags_AllowLongFormatPath)))
- return COR_E_BAD_PATHNAME;
-
- if (clr::fs::File::Exists(wzFullPathBuf))
- {
- DWORD cchPathName = *pcchPathName;
- *pcchPathName = cchFullPath;
- return StringCchCopy(pwzPathName, cchPathName, wzFullPathBuf);
- }
- }
- // If the path is absolute, see if the file name contains the pacakge root as a prefix
- // and if the file exists.
- else
- {
- DWORD cchPath = static_cast<DWORD>(wcslen(wzPath));
-
- // Determine if wzPath is a path prefix of wzFileName
- if (cchPath < cchFileName &&
- _wcsnicmp(wzPath, wzFileName, cchPath) == 0 &&
- (wzFileName[cchPath] == W('\\') || wzPath[cchPath-1] == W('\\'))) // Ensure wzPath is not just a prefix, but a path prefix
- {
- if (clr::fs::File::Exists(wzFileName))
- {
- DWORD cchPathName = *pcchPathName;
- *pcchPathName = cchFileName;
- return StringCchCopy(pwzPathName, cchPathName, wzFileName);
- }
- }
- }
-
- return S_FALSE;
- }; // FindFileInCurrentPackageHelper
-
- if (!(findInCurrentPackageFlags & FindFindInPackageFlags_SkipCurrentPackageGraph))
- {
- PCPACKAGE_INFO pCurNode = reinterpret_cast<PPACKAGE_INFO>(
- g_pAppXRTInfo->m_pCurrentPackageInfo->m_pbCurrentPackageInfo);
- PCPACKAGE_INFO pEndNode = pCurNode + g_pAppXRTInfo->m_pCurrentPackageInfo->m_nCount;
- for (; pCurNode != pEndNode; ++pCurNode)
- {
- IfFailRet(FindFileInCurrentPackageHelper(pCurNode->path));
-
- if (hr == S_OK)
- {
- return hr;
- }
-
- // End search if dependent packages should not be checked.
- if ((uiFlags & PACKAGE_FILTER_DIRECT) == 0)
- {
- break;
- }
- }
- }
-
- // Process alternative paths
- for (UINT iAltPath = 0; iAltPath < cAltPaths; iAltPath++)
- {
- IfFailRet(FindFileInCurrentPackageHelper(rgwzAltPaths[iAltPath]));
-
- if (hr == S_OK)
- {
- return hr;
- }
- }
-
- return E_FILE_NOT_FOUND;
- }
-#endif // FEATURE_APPX_BINDER
-
- //-----------------------------------------------------------------------------------------
- HRESULT GetAppContainerTokenInfoForProcess(
- DWORD dwPid,
- NewArrayHolder<BYTE>& pbAppContainerTokenInfo,
- DWORD* pcbAppContainerTokenInfo)
- {
- LIMITED_METHOD_CONTRACT;
-
- HRESULT hr = S_OK;
-
- pbAppContainerTokenInfo = nullptr;
-
- if (!IsAppXSupported())
- {
- return S_FALSE;
- }
-
- if (dwPid == GetCurrentProcessId())
- {
- if (FAILED(hr = CheckInitAppXRT()))
- {
- SetLastError(hr);
- return S_FALSE;
- }
-
- if (g_pAppXRTInfo->m_pbAppContainerInfo == nullptr)
- {
- return S_FALSE;
- }
- else
- {
- pbAppContainerTokenInfo = g_pAppXRTInfo->m_pbAppContainerInfo.GetValue();
- pbAppContainerTokenInfo.SuppressRelease(); // Caller does not need to free mem.
- if (pcbAppContainerTokenInfo != nullptr)
- {
- *pcbAppContainerTokenInfo = g_pAppXRTInfo->m_cbAppContainerInfo;
- }
- return S_OK;
- }
- }
- else
- {
- return ::GetAppContainerTokenInfoForProcess(dwPid, pbAppContainerTokenInfo, pcbAppContainerTokenInfo);
- }
- }
-
- // Called during NGen to pretend that we're in a certain package. Due to Windows restriction, we can't
- // start NGen worker processes in the right package environment (only in the right AppContainer). So
- // NGen calls this function with a package name, to indicate that all AppX-related code should behave as
- // if the current process is running in that package.
- HRESULT SetCurrentPackageForNGen(__in PCWSTR pszPackageFullName)
- {
- LIMITED_METHOD_CONTRACT;
-
- HRESULT hr = S_OK;
-
- IfFailRet(CheckInitAppXRT());
-
- _ASSERTE(IsAppXSupported());
- _ASSERTE(g_pAppXRTInfo->m_hAppXRTMod != nullptr);
-
- HMODULE hAppXRTMod = g_pAppXRTInfo->m_hAppXRTMod;
- OpenPackageInfoByFullName_t *pfnOpenPackageInfoByFullName
- = reinterpret_cast<OpenPackageInfoByFullName_t*>(GetProcAddress(hAppXRTMod, "OpenPackageInfoByFullName"));
- _ASSERTE(pfnOpenPackageInfoByFullName != nullptr);
- if (pfnOpenPackageInfoByFullName == nullptr)
- return HRESULT_FROM_GetLastError();
-
- ClosePackageInfo_t *pfnClosePackageInfo
- = reinterpret_cast<ClosePackageInfo_t*>(GetProcAddress(hAppXRTMod, "ClosePackageInfo"));
- _ASSERTE(pfnClosePackageInfo != nullptr);
- if (pfnClosePackageInfo == nullptr)
- return HRESULT_FROM_GetLastError();
-
- GetPackageInfo_t *pfnGetPackageInfo
- = reinterpret_cast<GetPackageInfo_t*>(GetProcAddress(hAppXRTMod, "GetPackageInfo"));
- _ASSERTE(pfnGetPackageInfo != nullptr);
- if (pfnGetPackageInfo == nullptr)
- return HRESULT_FROM_GetLastError();
-
- PACKAGE_INFO_REFERENCE packageInfoReference;
- hr = HRESULT_FROM_WIN32(pfnOpenPackageInfoByFullName(pszPackageFullName, 0, &packageInfoReference));
- if (FAILED(hr))
- return hr;
-
- // Automatically close packageInfoReference before we return.
- class PackageInfoReferenceHolder
- {
- public:
- PackageInfoReferenceHolder(ClosePackageInfo_t *pfnClosePackageInfo, PACKAGE_INFO_REFERENCE &packageInfoReference)
- :m_pfnClosePackageInfo(pfnClosePackageInfo),
- m_packageInfoReference(packageInfoReference)
- {
- }
- ~PackageInfoReferenceHolder() { m_pfnClosePackageInfo(m_packageInfoReference); }
- private:
- ClosePackageInfo_t *m_pfnClosePackageInfo;
- PACKAGE_INFO_REFERENCE &m_packageInfoReference;
- } pirh(pfnClosePackageInfo, packageInfoReference);
-
- UINT32 cbBuffer = 0;
- hr = HRESULT_FROM_WIN32(pfnGetPackageInfo(packageInfoReference, PACKAGE_FILTER_CLR_DEFAULT, &cbBuffer, nullptr, nullptr));
- if (hr != E_INSUFFICIENT_BUFFER)
- return hr;
-
- NewArrayHolder<BYTE> pbBuffer(new (nothrow) BYTE[cbBuffer]);
- IfNullRet(pbBuffer);
-
- UINT32 nCount = 0;
- IfFailRet(HRESULT_FROM_WIN32(pfnGetPackageInfo(packageInfoReference, PACKAGE_FILTER_CLR_DEFAULT, &cbBuffer, pbBuffer, &nCount)));
-
- NewHolder<AppXRTInfo::CurrentPackageInfo> pPkgInfo(
- new (nothrow) AppXRTInfo::CurrentPackageInfo(cbBuffer, pbBuffer.Extract(), nCount));
- IfNullRet(pPkgInfo);
-
- if (InterlockedCompareExchangeT<AppXRTInfo::CurrentPackageInfo>(
- &g_pAppXRTInfo->m_pCurrentPackageInfo, pPkgInfo, nullptr) == nullptr)
- {
- pPkgInfo.SuppressRelease();
- }
-
- g_pAppXRTInfo->m_fIsAppXProcess = true;
- g_pAppXRTInfo->m_fIsAppXNGen = true;
-
- return hr;
- }
-
-#endif // DACCESS_COMPILE
-} // namespace AppX
-
-
-#endif // FEATURE_CORECLR
//*****************************************************************************
// Initialize
//*****************************************************************************
-#ifndef FEATURE_CORECLR
-LPCWSTR CCompRC::m_pDefaultResource = W("mscorrc.dll");
-#else // !FEATURE_CORECLR
LPCWSTR CCompRC::m_pDefaultResource = W("mscorrc.debug.dll");
LPCWSTR CCompRC::m_pFallbackResource= W("mscorrc.dll");
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_PAL
LPCSTR CCompRC::m_pDefaultResourceDomain = "mscorrc.debug";
return &m_DefaultResourceDll;
}
-#ifdef FEATURE_CORECLR
LONG CCompRC::m_dwFallbackInitialized = 0;
CCompRC CCompRC::m_FallbackResourceDll;
return &m_FallbackResourceDll;
}
-#endif // FEATURE_CORECLR
//*****************************************************************************
// Failed to load string
if ( hr != E_OUTOFMEMORY && ShouldUseFallback())
{
-#ifdef FEATURE_CORECLR
CCompRC* pFallback=CCompRC::GetFallbackResourceDll();
if (pFallback)
{
if(SUCCEEDED(hr))
return hr;
}
-#endif
switch (eCategory)
{
case Optional:
hr = E_FAIL;
break;
-#ifdef FEATURE_CORECLR
case DesktopCLR:
hr = E_FAIL;
break;
// if we got here then we couldn't get the fallback message
// the fallback message is required so just falling through into "Required"
-#else // FEATURE_CORECLR
- // everything that's not optional goes here for Desktop
- case DesktopCLR:
- case Debugging:
- case Error:
-#endif
case Required:
if ( hr != E_OUTOFMEMORY)
PathString rcPath; // Path to resource DLL.
// Try first in the same directory as this dll.
-#if defined(FEATURE_CORECLR)
VALIDATECORECLRCALLBACKS();
hr = LoadLibraryHelper(pHInst, rcPath);
-#else // FEATURE_CORECLR
-
- if (!WszGetModuleFileName(GetModuleInst(), rcPath))
- return HRESULT_FROM_GetLastError();
-
- CopySystemDirectory(rcPath, rcPath);
-
- hr = LoadLibraryHelper(pHInst, rcPath);
- if (hr == E_OUTOFMEMORY)
- return hr;
-
- // In case of default rc file, also try CORSystemDirectory.
- // Note that GetRequestedRuntimeInfo is a function in ths shim. As of 12/06, this is the only
- // place where utilcode appears to take a dependency on the shim. This forces everyone that links
- // with us to also dynamically link to mscoree.dll. Perhaps this should be a delay-load to prevent
- // that static dependency and have a gracefull fallback when the shim isn't installed.
- // We don't do this in DAC builds because mscordacwks.dll cannot take a dependency on other CLR
- // dlls (eg. you must be able to examine a managed dump on a machine without any CLR installed).
-#ifndef DACCESS_COMPILE
- if (FAILED(hr) && m_pResourceFile == m_pDefaultResource)
- {
-#ifdef SELF_NO_HOST
- WCHAR rcVersion[MAX_VERSION_STRING];
- DWORD rcVersionSize;
-
- DWORD corSystemPathSize;
-
- // The reason for using GetRequestedRuntimeInfo is the ability to suppress message boxes
- // with RUNTIME_INFO_DONT_SHOW_ERROR_DIALOG.
- COUNT_T size = MAX_PATH;
- hr = LegacyActivationShim::GetRequestedRuntimeInfo(
- NULL,
- W("v")VER_PRODUCTVERSION_NO_QFE_STR_L,
- NULL,
- 0,
- RUNTIME_INFO_UPGRADE_VERSION|RUNTIME_INFO_DONT_SHOW_ERROR_DIALOG|RUNTIME_INFO_CONSIDER_POST_2_0,
- rcPath.OpenUnicodeBuffer(size-1),
- size,
- &corSystemPathSize,
- rcVersion,
- NumItems(rcVersion),
- &rcVersionSize);
-
- rcPath.CloseBuffer(corSystemPathSize);
-
- if (SUCCEEDED(hr))
- {
- if (rcVersionSize > 0)
- {
- rcPath.Append(rcVersion);
- rcPath.Append(W("\\"));
- }
- }
-#else
- // If we're hosted, we have the advantage of a CoreClrCallbacks reference.
- // More importantly, we avoid calling back to mscoree.dll.
-
- hr = GetClrCallbacks().m_pfnGetCORSystemDirectory(rcPath);
-#endif
- if (SUCCEEDED(hr))
- {
- hr = LoadLibraryHelper(pHInst, rcPath);
- }
- }
-#endif // !DACCESS_COMPILE
-
-#endif // FEATURE_CORECLR
#endif // CROSSGEN_COMPILE
#include "contract.h"
#include "tls.h"
-#if defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE) || defined(CROSSGEN_COMPILE)
CoreClrCallbacks g_CoreClrCallbacks;
-#endif
// In some cirumstance (e.g, the thread suspecd another thread), allocation on heap
#endif // FAILPOINTS_ENABLED
-#if defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
//-----------------------------------------------------------------------------------
// This is the approved way to get a module handle to mscorwks.dll (or coreclr.dll).
return g_CoreClrCallbacks.m_hmodCoreCLR;
}
-#endif // defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
#if defined(SELF_NO_HOST)
// versions in the same process.
//--------------------------------------------------------------------------
-#if defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
//--------------------------------------------------------------------------
// One-time initialized called by coreclr.dll in its dllmain.
}
#endif // _DEBUG
-#endif // defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
}
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-// The following functions are not used in CoreCLR. Normally LINKER can remove these functions
-// from generated files. But LINKER does it in two steps:
-// 1. If no function in a source file is used, the file is ignored by LINKER
-// 2. If one function is used, LINKER will first make sure all imported functions in the file
-// is available, and then it will remove unused functions.
-// Instead of specifying all libs for imported functions needed by the following codes, we just
-// remove them from compiling phase.
-__success(return)
-BOOL
-CreateUrlCacheEntryW_NoThrow(
- IN LPCWSTR lpszUrlName,
- IN DWORD dwExpectedFileSize,
- IN LPCWSTR lpszFileExtension,
- __out_ecount(MAX_LONGPATH+1) LPWSTR lpszFileName,
- IN DWORD dwReserved
- )
-{
- WRAPPER_NO_CONTRACT;
- HRESULT hr=S_OK;
- BOOL bRet=FALSE;
- EX_TRY
- {
- bRet=CreateUrlCacheEntryW(lpszUrlName,dwExpectedFileSize,lpszFileExtension,
- lpszFileName,dwReserved);
- }
- EX_CATCH_HRESULT(hr);
- if (hr!=S_OK)
- SetLastError(hr);
- return bRet;
-
-}
-
-BOOL
-CommitUrlCacheEntryW_NoThrow(
- IN LPCWSTR lpszUrlName,
- IN LPCWSTR lpszLocalFileName,
- IN FILETIME ExpireTime,
- IN FILETIME LastModifiedTime,
- IN DWORD CacheEntryType,
- IN LPCWSTR lpHeaderInfo,
- IN DWORD dwHeaderSize,
- IN LPCWSTR lpszFileExtension,
- IN LPCWSTR lpszOriginalUrl
- )
-{
- WRAPPER_NO_CONTRACT;
- HRESULT hr=S_OK;
- BOOL bRet=FALSE;
- EX_TRY
- {
- bRet=CommitUrlCacheEntryW(lpszUrlName,lpszLocalFileName,ExpireTime,
- LastModifiedTime,CacheEntryType,(LPWSTR)lpHeaderInfo,
- dwHeaderSize,lpszFileExtension,lpszOriginalUrl);
- }
- EX_CATCH_HRESULT(hr);
- if (hr!=S_OK)
- SetLastError(hr);
- return bRet;
-
-}
-
-BOOL
-InternetTimeToSystemTimeA_NoThrow(
- IN LPCSTR lpszTime, // NULL terminated string
- OUT SYSTEMTIME *pst, // output in GMT time
- IN DWORD dwReserved
- )
-{
- WRAPPER_NO_CONTRACT;
- HRESULT hr=S_OK;
- BOOL bRet=FALSE;
- EX_TRY
- {
- bRet=InternetTimeToSystemTimeA(lpszTime,pst,dwReserved);
- }
- EX_CATCH_HRESULT(hr);
- if (hr!=S_OK)
- SetLastError(hr);
- return bRet;
-
-}
-
-HRESULT
-CoInternetCreateSecurityManager_NoThrow(
- IServiceProvider *pSP,
- IInternetSecurityManager **ppSM,
- DWORD dwReserved
- )
-{
- WRAPPER_NO_CONTRACT;
- HRESULT hr=S_OK;
- EX_TRY
- {
- hr=CoInternetCreateSecurityManager(pSP,ppSM, dwReserved);
- }
- EX_CATCH_HRESULT(hr);
- return hr;
-}
-
-HRESULT
-URLDownloadToCacheFileW_NoThrow(
- LPUNKNOWN lpUnkcaller,
- LPCWSTR szURL,
- __out_ecount(dwBufLength) LPWSTR szFileName,
- DWORD dwBufLength,
- DWORD dwReserved,
- IBindStatusCallback *pBSC
- )
-{
- WRAPPER_NO_CONTRACT;
- HRESULT hr=S_OK;
- EX_TRY
- {
- hr=URLDownloadToCacheFileW(lpUnkcaller,szURL,szFileName,dwBufLength,dwReserved,pBSC);
- }
- EX_CATCH_HRESULT(hr);
- return hr;
-}
-
-HRESULT
-CoInternetGetSession_NoThrow(
- WORD dwSessionMode,
- IInternetSession **ppIInternetSession,
- DWORD dwReserved
- )
-{
- WRAPPER_NO_CONTRACT;
- HRESULT hr=S_OK;
- EX_TRY
- {
- hr=CoInternetGetSession(dwSessionMode,ppIInternetSession,dwReserved);
- }
- EX_CATCH_HRESULT(hr);
- return hr;
-}
-
-HRESULT
-CopyBindInfo_NoThrow(
- const BINDINFO * pcbiSrc, BINDINFO * pbiDest
- )
-{
- WRAPPER_NO_CONTRACT;
- HRESULT hr=S_OK;
- EX_TRY
- {
- hr=CopyBindInfo(pcbiSrc,pbiDest );
- }
- EX_CATCH_HRESULT(hr);
- return hr;
-}
-#endif // FEATURE_CORECLR && !CROSSGEN_COMPILE
exceptionArgs[0] = arg0;
-#if !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) && (defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE))
+#if !defined(FEATURE_UTILCODE_NO_DEPENDENCIES)
exceptionArgs[INSTANCE_TAGGED_SEH_PARAM_ARRAY_SIZE - 1] = (ULONG_PTR) (GetCLRModule());
#endif // !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) && defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
{
return FALSE;
}
-#if!defined(FEATURE_UTILCODE_NO_DEPENDENCIES) && (defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE))
+#if!defined(FEATURE_UTILCODE_NO_DEPENDENCIES)
if ( ((ULONG_PTR)(GetCLRModule())) != pcER->ExceptionInformation[INSTANCE_TAGGED_SEH_PARAM_ARRAY_SIZE - 1] )
{
return FALSE;
}
#endif //!FEATURE_PAL
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
#ifndef FEATURE_PAL
#endif // FEATURE_PAL
-#endif // FEATURE_CORECLR || CROSSGEN_COMPILE
//Implementation of LongFile Helpers
const WCHAR LongFile::DirectorySeparatorChar = W('\\');
#include "utilcode.h"
#include "ex.h"
-#ifndef FEATURE_CORECLR
-/***
-*void MakePath() - build path name from components
-*
-*Purpose:
-* create a path name from its individual components
-*
-*Entry:
-* WCHAR *path - pointer to buffer for constructed path
-* WCHAR *drive - pointer to drive component, may or may not contain
-* trailing ':'
-* WCHAR *dir - pointer to subdirectory component, may or may not include
-* leading and/or trailing '/' or '\' characters
-* WCHAR *fname - pointer to file base name component
-* WCHAR *ext - pointer to extension component, may or may not contain
-* a leading '.'.
-*
-*Exit:
-* path - pointer to constructed path name
-*
-*Exceptions:
-*
-*******************************************************************************/
-
-void MakePath (
- __out_ecount (MAX_LONGPATH) WCHAR *path,
- __in LPCWSTR drive,
- __in LPCWSTR dir,
- __in LPCWSTR fname,
- __in LPCWSTR ext
- )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- FORBID_FAULT;
- }
- CONTRACTL_END
-
- const WCHAR *p;
- DWORD count = 0;
-
- /* we assume that the arguments are in the following form (although we
- * do not diagnose invalid arguments or illegal filenames (such as
- * names longer than 8.3 or with illegal characters in them)
- *
- * drive:
- * A ; or
- * A:
- * dir:
- * \top\next\last\ ; or
- * /top/next/last/ ; or
- * either of the above forms with either/both the leading
- * and trailing / or \ removed. Mixed use of '/' and '\' is
- * also tolerated
- * fname:
- * any valid file name
- * ext:
- * any valid extension (none if empty or null )
- */
-
- /* copy drive */
-
- if (drive && *drive) {
- *path++ = *drive;
- *path++ = _T(':');
- count += 2;
- }
-
- /* copy dir */
-
- if ((p = dir)) {
- while (*p) {
- *path++ = *p++;
- count++;
-
- if (count == MAX_LONGPATH) {
- --path;
- *path = _T('\0');
- return;
- }
- }
-
-#ifdef _MBCS
- if (*(p=_mbsdec(dir,p)) != _T('/') && *p != _T('\\')) {
-#else /* _MBCS */
- // suppress warning for the following line; this is safe but would require significant code
- // delta for prefast to understand.
-#ifdef _PREFAST_
- #pragma warning( suppress: 26001 )
-#endif
- if (*(p-1) != _T('/') && *(p-1) != _T('\\')) {
-#endif /* _MBCS */
- *path++ = _T('\\');
- count++;
-
- if (count == MAX_LONGPATH) {
- --path;
- *path = _T('\0');
- return;
- }
- }
- }
-
- /* copy fname */
-
- if ((p = fname)) {
- while (*p) {
- *path++ = *p++;
- count++;
-
- if (count == MAX_LONGPATH) {
- --path;
- *path = _T('\0');
- return;
- }
- }
- }
-
- /* copy ext, including 0-terminator - check to see if a '.' needs
- * to be inserted.
- */
-
- if ((p = ext)) {
- if (*p && *p != _T('.')) {
- *path++ = _T('.');
- count++;
-
- if (count == MAX_LONGPATH) {
- --path;
- *path = _T('\0');
- return;
- }
- }
-
- while ((*path++ = *p++)) {
- count++;
-
- if (count == MAX_LONGPATH) {
- --path;
- *path = _T('\0');
- return;
- }
- }
- }
- else {
- /* better add the 0-terminator */
- *path = _T('\0');
- }
-}
-#endif // !FEATURE_CORECLR
/***
*void Makepath() - build path name from components
szPath.Shrink(count + 1);
}
-#if !defined(FEATURE_CORECLR)
-static LPCWSTR g_wszProcessExePath = NULL;
-
-HRESULT GetProcessExePath(LPCWSTR *pwszProcessExePath)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- CONSISTENCY_CHECK(CheckPointer(pwszProcessExePath));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- if (g_wszProcessExePath == NULL)
- {
- DWORD cchProcName = 0;
- NewArrayHolder<WCHAR> wszProcName;
- EX_TRY
- {
- PathString wszProcNameString;
- cchProcName = WszGetModuleFileName(NULL, wszProcNameString);
- if (cchProcName == 0)
- {
- hr = HRESULT_FROM_GetLastError();
- }
- else
- {
- wszProcName = wszProcNameString.GetCopyOfUnicodeString();
- }
- }
- EX_CATCH_HRESULT(hr);
-
- if (FAILED(hr))
- {
- return hr;
- }
-
- if (InterlockedCompareExchangeT(&g_wszProcessExePath, const_cast<LPCWSTR>(wszProcName.GetValue()), NULL) == NULL)
- {
- wszProcName.SuppressRelease();
- }
- }
- _ASSERTE(g_wszProcessExePath != NULL);
- _ASSERTE(SUCCEEDED(hr));
-
- *pwszProcessExePath = g_wszProcessExePath;
- return hr;
-}
-#endif
// Returns the directory for HMODULE. So, if HMODULE was for "C:\Dir1\Dir2\Filename.DLL",
// then this would return "C:\Dir1\Dir2\" (note the trailing backslash).
FARPROC result = NULL;
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-
- // First try to use the function defined in the culture dll
- // if we are running on a platform prior to Win7
- if(!IsWindows7Platform())
- {
- // only need to load the culture dll's handle once then we can hold onto it
- static HMODULE hCulture = NULL;
- // if we haven't loaded the culture dll yet
- if (hCulture == NULL)
- {
- UtilCode::LoadLibraryShim(MAKEDLLNAME_W(W("culture")), NULL, 0, &hCulture);
- }
-
- // make sure we were successful before using the handle
- if (hCulture != NULL)
- {
- result=GetProcAddress(hCulture,lpProcName);
- }
- }
-#endif // !FEATURE_CORECLR && !CROSSGEN_COMPILE
// next try the kernel
if(result==NULL)
retVal = ::LCIDToLocaleName(Locale, lpName, cchName, dwFlags | LOCALE_ALLOW_NEUTRAL_NAMES);
#else
-#ifdef FEATURE_CORECLR
retVal = DownLevel::LCIDToLocaleName(Locale, lpName,cchName,dwFlags | LOCALE_ALLOW_NEUTRAL_NAMES);
-#endif // FEATURE_CORECLR
typedef int (WINAPI *PFNLCIDToLocaleName)(LCID, LPWSTR,int ,DWORD);
static PFNLCIDToLocaleName pFNLCIDToLocaleName=NULL;
#if !defined(ENABLE_DOWNLEVEL_FOR_NLS)
return ::LocaleNameToLCID(lpName, dwFlags | LOCALE_ALLOW_NEUTRAL_NAMES);
#else
-#ifdef FEATURE_CORECLR
retVal = DownLevel::LocaleNameToLCID(lpName, dwFlags | LOCALE_ALLOW_NEUTRAL_NAMES);
-#endif // FEATURE_CORECLR
typedef int (WINAPI *PFNLocaleNameToLCID)(LPCWSTR,DWORD);
static PFNLocaleNameToLCID pFNLocaleNameToLCID=NULL;
}
-#if !defined(FEATURE_CORECLR)
- BOOL GetNlsVersionEx(__in NLS_FUNCTION Function, __in LPCWSTR lpLocaleName, __inout LPNLSVERSIONINFOEX lpVersionInfo)
- {
-
- typedef BOOL (WINAPI *PFNGetNLSVersionEx)(NLS_FUNCTION, LPCWSTR, LPNLSVERSIONINFOEX);
-
- static PFNGetNLSVersionEx pFNGetNLSVersionEx=NULL;
-
- // See if we still need to find our function
- if (pFNGetNLSVersionEx == NULL)
- {
- // We only call this on Win8 and above, so this should always work.
- pFNGetNLSVersionEx = (PFNGetNLSVersionEx) GetSystemProcAddressForSortingApi("GetNLSVersionEx", NULL);
- }
-
- _ASSERTE(pFNGetNLSVersionEx != NULL);
-
- return pFNGetNLSVersionEx(Function, lpLocaleName, lpVersionInfo);
- }
-#endif
// This is a Windows 7 and above function
// This returns the "specific" locale from an input name, ie: "en" returns "en-US",
CHECK_OK;
}
-#if !defined(FEATURE_CORECLR)
-#define WHIDBEY_SP2_VERSION_MAJOR 2
-#define WHIDBEY_SP2_VERSION_MINOR 0
-#define WHIDBEY_SP2_VERSION_BUILD 50727
-#define WHIDBEY_SP2_VERSION_PRIVATE_BUILD 3053
-#endif // !defined(FEATURE_CORECLR)
// This function exists to provide compatibility between two different native image
// COR_HEADER and so the value of pDirRet is correct
if (HasNativeHeader())
{
-#ifdef FEATURE_CORECLR
if (type == METADATA_SECTION_MANIFEST)
pDirRet = &GetNativeHeader()->ManifestMetaData;
-#else // FEATURE_CORECLR
-
- IMAGE_DATA_DIRECTORY *pDirNativeHeader = &GetNativeHeader()->ManifestMetaData;
-
- // This code leverages the fact that pre-Whidbey SP2 private build numbers can never
- // be greater than Whidbey SP2 private build number, because otherwise major setup
- // issues would arise. To prevent this, it is standard to bump the private build
- // number up a significant amount for SPs, as was the case between Whidbey SP1 and
- // Whidbey SP2.
- //
- // Since we could be reading an older version of native image, we tell
- // GetNativeVersionInfoMaybeNull to skip checking the native header.
- CORCOMPILE_VERSION_INFO *pVerInfo = GetNativeVersionInfoMaybeNull(true);
- bool fIsPreWhidbeySP2 = false;
-
- // If pVerInfo is NULL, we assume that we're in an NGEN compilation domain and that
- // the information has not yet been written. Since an NGEN compilation domain running
- // in the v4.0 runtime can only complie v4.0 native images, we'll assume the default
- // fIsPreWhidbeySP2 value (false) is correct.
- if (pVerInfo != NULL && pVerInfo->wVersionMajor <= WHIDBEY_SP2_VERSION_MAJOR)
- {
- if (pVerInfo->wVersionMajor < WHIDBEY_SP2_VERSION_MAJOR)
- fIsPreWhidbeySP2 = true;
- else if (pVerInfo->wVersionMajor == WHIDBEY_SP2_VERSION_MAJOR)
- {
- // If the sp2 minor version isn't 0, we need this logic:
- // if (pVerInfo->wVersionMinor < WHIDBEY_SP2_VERSION_MINOR)
- // fIsPreWhidbeySP2 = true;
- // else
- // However, if it is zero, with that logic we get a warning about the comparison
- // of an unsigned variable to zero always being false.
- _ASSERTE(WHIDBEY_SP2_VERSION_MINOR == 0);
-
- if (pVerInfo->wVersionMinor == WHIDBEY_SP2_VERSION_MINOR)
- {
- if (pVerInfo->wVersionBuildNumber < WHIDBEY_SP2_VERSION_BUILD)
- fIsPreWhidbeySP2 = true;
- else if (pVerInfo->wVersionBuildNumber == WHIDBEY_SP2_VERSION_BUILD)
- {
- if (pVerInfo->wVersionPrivateBuildNumber < WHIDBEY_SP2_VERSION_PRIVATE_BUILD)
- fIsPreWhidbeySP2 = true;
- }
- }
- }
- }
-
- // In pre-Whidbey SP2, pDirRet points to manifest and pDirNativeHeader points to full.
- if (fIsPreWhidbeySP2)
- {
- if (type == METADATA_SECTION_FULL)
- pDirRet = pDirNativeHeader;
- }
- // In Whidbey SP2 and later, pDirRet points to full and pDirNativeHeader points to manifest.
- else
- {
- if (type == METADATA_SECTION_MANIFEST)
- pDirRet = pDirNativeHeader;
- }
-
-#endif // FEATURE_CORECLR
}
#include "clrconfig.h"
#include "strsafe.h"
-#if !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) && !defined(FEATURE_CORECLR)
-
-static LPCWSTR kRegistryRootKey = W("SOFTWARE\\");
-static const HKEY kRegistryRootHive = HKEY_LOCAL_MACHINE;
-static LPCWSTR kWow6432Node = W("Wow6432Node\\");
-static LPCWSTR kMicrosoftDotNetFrameworkPolicy = W("Microsoft\\.NETFramework\\Policy");
-static LPCWSTR wszHKLM = W("HKLM\\");
-static WCHAR * g_registryRoot = NULL;
-static volatile bool g_initialized = false;
-static const WCHAR BACKSLASH_CHARACTER[] = W("\\");
-
-//
-// Called the first time we use ClrRegCreateKeyEx or ClrRegOpenKeyEx to determine if the registry redirection
-// config value has been set. If so, we parse it into g_registryRoot
-// If the config string is mal-formed, we don't set the global variable.
-//
-HRESULT ParseRegistryRootConfigValue()
-{
- if (!IsNgenOffline())
- {
- return ERROR_SUCCESS;
- }
-
- CLRConfigStringHolder configValue(CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_RegistryRoot));
- // Since IsNgenOffline returned true, this better not be NULL
- if (configValue == NULL)
- return ERROR_BAD_ARGUMENTS;
-
- if (_wcsnicmp(configValue, wszHKLM, wcslen(wszHKLM)) != 0)
- {
- return ERROR_BAD_ARGUMENTS;
- }
-
- // The rest of the string is the location of the redirected registry key
- LPWSTR configValueKey = (LPWSTR)configValue;
- configValueKey = _wcsninc(configValueKey, wcslen(wszHKLM));
-
- size_t len = wcslen(configValueKey) + 1;
-
- bool appendBackslash = false;
- if (configValueKey[wcslen(configValueKey) - 1] != W('\\'))
- {
- appendBackslash = true;
- len += wcslen(BACKSLASH_CHARACTER);
- }
- g_registryRoot = new (nothrow) WCHAR[len];
-
- if (g_registryRoot == NULL)
- {
- return ERROR_NOT_ENOUGH_MEMORY;
- }
-
- wcscpy_s(g_registryRoot, len, configValueKey);
- if (appendBackslash)
- {
- StringCchCat(g_registryRoot, len, BACKSLASH_CHARACTER);
- }
-
- return ERROR_SUCCESS;
-}
-
-//
-// This is our check that the target machine is 32/64bit
-// If 32bit only, there will be no Wow6432Node key
-// If 64bit, there will be a Wow6432Node key
-//
-HRESULT CheckWow6432NodeNetFxExists(bool * fResult)
-{
- static bool bInitialized = false;
- static bool bNodeExists = false;
- HRESULT hr = ERROR_SUCCESS;
-
- if (!bInitialized)
- {
- size_t redirectedLength = wcslen(g_registryRoot) + wcslen(kWow6432Node) + wcslen(kMicrosoftDotNetFrameworkPolicy) + 1;
- LPWSTR lpRedirectedKey = new (nothrow) WCHAR[redirectedLength];
-
- if (lpRedirectedKey == NULL)
- {
- return ERROR_NOT_ENOUGH_MEMORY;
- }
-
- wcscpy_s(lpRedirectedKey, redirectedLength, g_registryRoot);
- StringCchCat(lpRedirectedKey, redirectedLength, kWow6432Node);
- StringCchCat(lpRedirectedKey, redirectedLength, kMicrosoftDotNetFrameworkPolicy);
-
- HKEY hkey;
- hr = RegOpenKeyExW(HKEY_LOCAL_MACHINE, lpRedirectedKey, 0, KEY_READ, &hkey);
- bNodeExists = hr == ERROR_SUCCESS;
-
- if (hr == ERROR_FILE_NOT_FOUND)
- {
- hr = ERROR_SUCCESS;
- }
-
- if (hkey)
- {
- RegCloseKey(hkey);
- }
- bInitialized = true;
- }
- *fResult = bNodeExists;
- return hr;
-}
-
-HRESULT CheckUseWow6432Node(REGSAM samDesired, bool * fResult)
-{
- HRESULT hr = ERROR_SUCCESS;
- bool fWow6432NodeExists = false;
-
- hr = CheckWow6432NodeNetFxExists(&fWow6432NodeExists);
- if (hr == ERROR_SUCCESS)
- {
- if (!fWow6432NodeExists)
- {
- *fResult = false;
- } else
- {
-#if defined(_WIN64)
- *fResult = false;
-#else
- *fResult = true;
-#endif
- // If KEY_WOW64_64KEY or KEY_WOW64_32KEY are set, override
- // If both are set, the actual registry call will fail with ERROR_INVALID_PARAMETER
- // so no worries here
- if (samDesired & KEY_WOW64_64KEY)
- {
- *fResult = false;
- } else if (samDesired & KEY_WOW64_32KEY)
- {
- *fResult = true;
- }
- }
- }
- return hr;
-}
-
-//
-// lpRedirectedKey is allocated and returned from this method. Caller owns the new string and
-// should release
-//
-__success(return == ERROR_SUCCESS)
-HRESULT RedirectKey(REGSAM samDesired, HKEY hKey, LPCWSTR lpKey, __deref_out_z LPWSTR * lpRedirectedKey)
-{
- if (hKey != kRegistryRootHive || _wcsnicmp(lpKey, kRegistryRootKey, wcslen(kRegistryRootKey)) != 0)
- {
- *lpRedirectedKey = NULL;
- return ERROR_SUCCESS;
- }
-
- LPCWSTR lpRootStrippedKey = lpKey + wcslen(kRegistryRootKey);
- size_t redirectedLength = wcslen(g_registryRoot) + wcslen(lpRootStrippedKey) + 1;
-
- bool bUseWow = false;
- HRESULT hr = CheckUseWow6432Node(samDesired, &bUseWow);
-
- if (hr != ERROR_SUCCESS)
- {
- return hr;
- }
-
- if (bUseWow)
- {
- redirectedLength += wcslen(kWow6432Node);
- }
-
- *lpRedirectedKey = new (nothrow) WCHAR[redirectedLength];
-
- if (*lpRedirectedKey == NULL)
- {
- return ERROR_NOT_ENOUGH_MEMORY;
- }
-
- wcscpy_s(*lpRedirectedKey, redirectedLength, g_registryRoot);
- if (bUseWow)
- {
- StringCchCat(*lpRedirectedKey, redirectedLength, kWow6432Node);
- }
-
- StringCchCat(*lpRedirectedKey, redirectedLength, lpRootStrippedKey);
-
- return ERROR_SUCCESS;
-}
-
-LONG ClrRegCreateKeyEx(
- HKEY hKey,
- LPCWSTR lpSubKey,
- DWORD Reserved,
- __in_opt LPWSTR lpClass,
- DWORD dwOptions,
- REGSAM samDesired,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes,
- PHKEY phkResult,
- LPDWORD lpdwDisposition
- )
-{
- HRESULT hr;
- if (!g_initialized)
- {
- hr = ParseRegistryRootConfigValue();
- if (hr != ERROR_SUCCESS)
- return hr;
- g_initialized = true;
- }
-
- if (g_registryRoot != NULL)
- {
- NewArrayHolder<WCHAR> lpRedirectedKey(NULL);
- hr = RedirectKey(samDesired, hKey, lpSubKey, &lpRedirectedKey);
- // We don't want to touch the registry if we're low on memory and can't redirect properly. It could lead
- // to use reading and writing to two separate registries and corrupting both in the process
- if (hr != ERROR_SUCCESS)
- return hr;
- LPCWSTR lpKeyToUse = lpRedirectedKey == NULL ? lpSubKey : lpRedirectedKey;
- return RegCreateKeyExW(hKey, lpKeyToUse, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
- }
- return RegCreateKeyExW(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
-} // ClrRegCreateKeyEx
-
-LONG ClrRegOpenKeyEx(
- HKEY hKey,
- LPCWSTR lpSubKey,
- DWORD ulOptions,
- REGSAM samDesired,
- PHKEY phkResult
- )
-{
- HRESULT hr;
- if (!g_initialized)
- {
- hr = ParseRegistryRootConfigValue();
- if (hr != ERROR_SUCCESS)
- return hr;
- g_initialized = true;
- }
-
- if (g_registryRoot != NULL)
- {
- NewArrayHolder<WCHAR> lpRedirectedKey(NULL);
- hr = RedirectKey(samDesired, hKey, lpSubKey, &lpRedirectedKey);
- // We don't want to touch the registry if we're low on memory and can't redirect properly. It could lead
- // to use reading and writing to two separate registries and corrupting both in the process
- if (hr != ERROR_SUCCESS)
- return hr;
- LPCWSTR lpKeyToUse = lpRedirectedKey == NULL ? lpSubKey : lpRedirectedKey;
- return RegOpenKeyExW(hKey, lpKeyToUse, ulOptions, samDesired, phkResult);
- }
- return RegOpenKeyExW(hKey, lpSubKey, ulOptions, samDesired, phkResult);
-}
-
-//
-// Determine whether we're running Offline Ngen for Build Lab based on the settings of several Config Values.
-//
-bool IsNgenOffline()
-{
- static volatile bool fInitialized = false;
- static volatile bool fNgenOffline = false;
-
- if (!fInitialized)
- {
- REGUTIL::CORConfigLevel kCorConfigLevel = static_cast<REGUTIL::CORConfigLevel>(REGUTIL::COR_CONFIG_ENV);
- CLRConfigStringHolder pwzConfigInstallRoot = REGUTIL::GetConfigString_DontUse_(CLRConfig::INTERNAL_InstallRoot,
- TRUE /* Prepend Complus */,
- kCorConfigLevel,
- FALSE /* fUsePerfCache */);
- CLRConfigStringHolder pwzConfigNicPath(CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_NicPath));
- CLRConfigStringHolder pwzRegistryRoot(CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_RegistryRoot));
- CLRConfigStringHolder pwzConfigAssemblyPath(CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_AssemblyPath));
- CLRConfigStringHolder pwzConfigAssemblyPath2(CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_AssemblyPath2));
- if (pwzConfigInstallRoot != NULL &&
- pwzConfigNicPath != NULL &&
- pwzConfigAssemblyPath != NULL &&
- pwzConfigAssemblyPath2 != NULL &&
- pwzRegistryRoot != NULL)
- {
- fNgenOffline = true;
- }
- fInitialized = true;
- }
-
- return fNgenOffline;
-}
-
-#endif //!FEATURE_UTILCODE_NO_DEPENDENCIES && !FEATURE_CORECLR
#ifdef ALLOW_REGISTRY
-#ifndef FEATURE_CORECLR
-
-//*****************************************************************************
-// Gives the use the ability to turn on/off REGUTIL's ability to read from
-// the registry. This is useful in mscoree.dll on startup, in order to avoid
-// loading advapi32 and rpcrt4 until we're ready for them
-//*****************************************************************************
-void REGUTIL::AllowRegistryUse(BOOL fAllowUse)
-{
- s_fUseRegistry = fAllowUse;
-}// AllowRegistryUse
-
-#endif // !FEATURE_CORECLR
#endif // ALLOW_REGISTRY
#ifdef ALLOW_REGISTRY
-#ifndef FEATURE_CORECLR
-
-//*****************************************************************************
-// Open's the given key and returns the value desired. If the key or value is
-// not found, then the default is returned.
-//*****************************************************************************
-long REGUTIL::GetLong( // Return value from registry or default.
- LPCTSTR szName, // Name of value to get.
- long iDefault, // Default value to return if not found.
- LPCTSTR szKey, // Name of key, NULL==default.
- HKEY hKeyVal) // What key to work on.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- FORBID_FAULT;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- long iValue; // The value to read.
- DWORD iType; // Type of value to get.
- DWORD iSize; // Size of buffer.
- HKEY hKey; // Key for the registry entry.
-
- _ASSERTE(UseRegistry());
-
- FAULT_NOT_FATAL(); // We don't report OOM errors here, we return a default value.
-
- // Open the key if it is there.
- if (ERROR_SUCCESS != WszRegOpenKeyEx(hKeyVal, (szKey) ? szKey : FRAMEWORK_REGISTRY_KEY_W, 0, KEY_READ, &hKey))
- return (iDefault);
-
- // Read the key value if found.
- iType = REG_DWORD;
- iSize = sizeof(long);
- if (ERROR_SUCCESS != WszRegQueryValueEx(hKey, szName, NULL,
- &iType, (LPBYTE)&iValue, &iSize) || iType != REG_DWORD)
- iValue = iDefault;
-
- // We're done with the key now.
- VERIFY(!RegCloseKey(hKey));
- return (iValue);
-}
-
-
-// Opens or creates desired reg key, then writes iValue
-//*****************************************************************************
-long REGUTIL::SetOrCreateLong( // Return value from registry or default.
- LPCTSTR szName, // Name of value to get.
- long iValue, // Value to set.
- LPCTSTR szKey, // Name of key, NULL==default.
- HKEY hKeyVal) // What key to work on.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- _ASSERTE(UseRegistry());
-
- long lRtn; // Return code.
- HKEY hKey; // Key for the registry entry.
-
-
- // Open the key if it is there, else create it
- if (WszRegCreateKeyEx(hKeyVal,
- (szKey) ? szKey : FRAMEWORK_REGISTRY_KEY_W,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_WRITE,
- NULL,
- &hKey,
- NULL) != ERROR_SUCCESS)
- {
- return (-1);
- }
-
- // Read the key value if found.
- lRtn = WszRegSetValueEx(hKey, szName, NULL, REG_DWORD, (const BYTE *) &iValue, sizeof(DWORD));
-
- // We're done with the key now.
- VERIFY(!RegCloseKey(hKey));
- return (lRtn);
-}
-
-
-//*****************************************************************************
-// Open's the given key and returns the value desired. If the key or value is
-// not found, then the default is returned.
-//*****************************************************************************
-long REGUTIL::SetLong( // Return value from registry or default.
- LPCTSTR szName, // Name of value to get.
- long iValue, // Value to set.
- LPCTSTR szKey, // Name of key, NULL==default.
- HKEY hKeyVal) // What key to work on.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- _ASSERTE(UseRegistry());
-
- long lRtn; // Return code.
- HKEY hKey; // Key for the registry entry.
-
- // Open the key if it is there.
- if (ERROR_SUCCESS != WszRegOpenKey(hKeyVal, (szKey) ? szKey : FRAMEWORK_REGISTRY_KEY_W, &hKey))
- return (-1);
-
- // Read the key value if found.
- lRtn = WszRegSetValueEx(hKey, szName, NULL, REG_DWORD, (const BYTE *) &iValue, sizeof(DWORD));
-
- // We're done with the key now.
- VERIFY(!RegCloseKey(hKey));
- return (lRtn);
-}
-
-//*****************************************************************************
-// Set an entry in the registry of the form:
-// HKEY_CLASSES_ROOT\szKey\szSubkey = szValue. If szSubkey or szValue are
-// NULL, omit them from the above expression.
-//*****************************************************************************
-BOOL REGUTIL::SetKeyAndValue( // TRUE or FALSE.
- LPCTSTR szKey, // Name of the reg key to set.
- LPCTSTR szSubkey, // Optional subkey of szKey.
- LPCTSTR szValue) // Optional value for szKey\szSubkey.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- _ASSERTE(UseRegistry());
-
- size_t nLen = _tcslen(szKey) + 1;
- if (szSubkey)
- nLen += (_tcslen(szSubkey) + 1);
-
- NewArrayHolder<TCHAR> rcKey = new (nothrow) TCHAR[nLen]; // Buffer for the full key name.
- if (rcKey == NULL)
- return FALSE;
-
- HKEY hKey = NULL; // Handle to the new reg key.
-
- // Init the key with the base key name.
- _tcscpy_s(rcKey, nLen, szKey);
-
- // Append the subkey name (if there is one).
- if (szSubkey != NULL)
- {
- _tcscat_s(rcKey, nLen, _T("\\"));
- _tcscat_s(rcKey, nLen, szSubkey);
- }
-
- // Create the registration key.
- if (WszRegCreateKeyEx(HKEY_CLASSES_ROOT, rcKey, 0, NULL,
- REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
- &hKey, NULL) != ERROR_SUCCESS)
- return(FALSE);
-
- // Set the value (if there is one).
- if (szValue != NULL)
- if( WszRegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *) szValue,
- (Wszlstrlen(szValue)+1) * sizeof(TCHAR)) != ERROR_SUCCESS ) {
- VERIFY(!RegCloseKey(hKey));
- return(FALSE);
- }
-
- VERIFY(!RegCloseKey(hKey));
- return(TRUE);
-}
-
-
-//*****************************************************************************
-// Delete an entry in the registry of the form:
-// HKEY_CLASSES_ROOT\szKey\szSubkey.
-//*****************************************************************************
-LONG REGUTIL::DeleteKey( // TRUE or FALSE.
- LPCTSTR szKey, // Name of the reg key to set.
- LPCTSTR szSubkey) // Subkey of szKey.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- _ASSERTE(UseRegistry());
-
- size_t nLen = _tcslen(szKey) + 1;
- if (szSubkey)
- nLen += (_tcslen(szSubkey) + 1);
-
- NewArrayHolder<TCHAR> rcKey = new (nothrow) TCHAR[nLen]; // Buffer for the full key name.
- if (rcKey == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Init the key with the base key name.
- _tcscpy_s(rcKey, nLen, szKey);
-
- // Append the subkey name (if there is one).
- if (szSubkey != NULL)
- {
- _tcscat_s(rcKey, nLen, _T("\\"));
- _tcscat_s(rcKey, nLen, szSubkey);
- }
-
- // Delete the registration key.
- return WszRegDeleteKey(HKEY_CLASSES_ROOT, rcKey);
-}
-
-
-//*****************************************************************************
-// Open the key, create a new keyword and value pair under it.
-//*****************************************************************************
-BOOL REGUTIL::SetRegValue( // Return status.
- LPCTSTR szKeyName, // Name of full key.
- LPCTSTR szKeyword, // Name of keyword.
- LPCTSTR szValue) // Value of keyword.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- _ASSERTE(UseRegistry());
-
- HKEY hKey; // Handle to the new reg key.
-
- // Create the registration key.
- if (WszRegCreateKeyEx(HKEY_CLASSES_ROOT, szKeyName, 0, NULL,
- REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
- &hKey, NULL) != ERROR_SUCCESS)
- return (FALSE);
-
- // Set the value (if there is one).
- if (szValue != NULL)
- if( WszRegSetValueEx(hKey, szKeyword, 0, REG_SZ, (BYTE *)szValue,
- (Wszlstrlen(szValue)+1) * sizeof(TCHAR)) != ERROR_SUCCESS) {
- VERIFY(!RegCloseKey(hKey));
- return(FALSE);
- }
-
- VERIFY(!RegCloseKey(hKey));
- return (TRUE);
-}
-
-
-//*****************************************************************************
-// Does standard registration of a CoClass with a progid.
-//*****************************************************************************
-HRESULT REGUTIL::RegisterCOMClass( // Return code.
- REFCLSID rclsid, // Class ID.
- LPCTSTR szDesc, // Description of the class.
- LPCTSTR szProgIDPrefix, // Prefix for progid.
- int iVersion, // Version # for progid.
- LPCTSTR szClassProgID, // Class progid.
- LPCTSTR szThreadingModel, // What threading model to use.
- LPCTSTR szModule, // Path to class.
- HINSTANCE hInst, // Handle to module being registered
- LPCTSTR szAssemblyName, // Optional Assembly,
- LPCTSTR szVersion, // Optional Runtime version (directory containing runtime)
- BOOL fExternal, // flag - External to mscoree.
- BOOL fRelativePath) // flag - Relative path in szModule
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- WCHAR rcCLSID[256]; // CLSID\\szID.
- WCHAR rcInproc[_MAX_PATH+64]; // CLSID\\InprocServer32
- WCHAR rcProgID[256]; // szProgIDPrefix.szClassProgID
- WCHAR rcIndProgID[256]; // rcProgID.iVersion
- WCHAR rcShim[_MAX_PATH];
- HRESULT hr;
-
- // Format the prog ID values.
- VERIFY(_snwprintf_s(rcIndProgID, _countof(rcIndProgID), _TRUNCATE, W("%s.%s"), szProgIDPrefix, szClassProgID));
-
- VERIFY(_snwprintf_s(rcProgID, _countof(rcProgID), _TRUNCATE, W("%s.%d"), rcIndProgID, iVersion));
-
- // Do the initial portion.
- if (FAILED(hr = RegisterClassBase(rclsid, szDesc, rcProgID, rcIndProgID, rcCLSID, NumItems(rcCLSID))))
- return (hr);
-
- VERIFY(_snwprintf_s(rcInproc, _countof(rcInproc), _TRUNCATE, W("%s\\%s"), rcCLSID, W("InprocServer32")));
-
- if (!fExternal){
- SetKeyAndValue(rcCLSID, W("InprocServer32"), szModule);
- }
- else{
- LPCTSTR pSep = szModule;
- if (!fRelativePath && szModule) {
- pSep = wcsrchr(szModule, W('\\'));
- if(pSep == NULL)
- pSep = szModule;
- else
- pSep++;
- }
- HMODULE hMod = WszLoadLibrary(W("mscoree.dll"));
- if (!hMod)
- return E_FAIL;
-
- DWORD ret;
- VERIFY(ret = WszGetModuleFileName(hMod, rcShim, NumItems(rcShim)));
- FreeLibrary(hMod);
- if( !ret )
- return E_FAIL;
-
- // Set the server path.
- SetKeyAndValue(rcCLSID, W("InprocServer32"), rcShim);
- if(pSep)
- SetKeyAndValue(rcCLSID, W("Server"), pSep);
-
- if(szAssemblyName) {
- SetRegValue(rcInproc, W("Assembly"), szAssemblyName);
- SetRegValue(rcInproc, W("Class"), rcIndProgID);
- }
- }
-
- // Set the runtime version, it needs to be passed in from the outside
- if(szVersion != NULL) {
- LPCTSTR pSep2 = NULL;
- LPTSTR pSep1 = const_cast<LPTSTR>(wcsrchr(szVersion, W('\\')));
- if(pSep1 != NULL) {
- *pSep1 = '\0';
- pSep2 = wcsrchr(szVersion, W('\\'));
- if (!pSep2)
- pSep2 = szVersion;
- else
- pSep2 = pSep2++; // exclude '\\'
- }
- else
- pSep2 = szVersion;
-
- size_t bufLen = wcslen(rcInproc)+wcslen(pSep2)+2;
- WCHAR* rcVersion = new (nothrow) WCHAR[bufLen];
- if(rcVersion==NULL)
- return (E_OUTOFMEMORY);
- wcscpy_s(rcVersion, bufLen, rcInproc);
- wcscat_s(rcVersion, bufLen, W("\\"));
- wcscat_s(rcVersion, bufLen, pSep2);
- SetRegValue(rcVersion, W("ImplementedInThisVersion"), W(""));
- delete[] rcVersion;
-
- if(pSep1 != NULL)
- *pSep1 = W('\\');
- }
-
- // Add the threading model information.
- SetRegValue(rcInproc, W("ThreadingModel"), szThreadingModel);
- return (S_OK);
-}
-
-
-
-//*****************************************************************************
-// Does standard registration of a CoClass with a progid.
-// NOTE: This is the non-side-by-side execution version.
-//*****************************************************************************
-HRESULT REGUTIL::RegisterCOMClass( // Return code.
- REFCLSID rclsid, // Class ID.
- LPCTSTR szDesc, // Description of the class.
- LPCTSTR szProgIDPrefix, // Prefix for progid.
- int iVersion, // Version # for progid.
- LPCTSTR szClassProgID, // Class progid.
- LPCTSTR szThreadingModel, // What threading model to use.
- LPCTSTR szModule, // Path to class.
- BOOL bInprocServer) // Whether we register the server as inproc or local
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- WCHAR rcCLSID[256]; // CLSID\\szID.
- WCHAR rcInproc[_MAX_PATH+64]; // CLSID\\InprocServer32
- WCHAR rcProgID[256]; // szProgIDPrefix.szClassProgID
- WCHAR rcIndProgID[256]; // rcProgID.iVersion
- HRESULT hr;
-
- // Format the prog ID values.
- VERIFY(_snwprintf_s(rcIndProgID, _countof(rcIndProgID), _TRUNCATE, W("%s.%s"), szProgIDPrefix, szClassProgID));
-
- VERIFY(_snwprintf_s(rcProgID, _countof(rcProgID), _TRUNCATE, W("%s.%d"), rcIndProgID, iVersion));
-
- // Do the initial portion.
- if (FAILED(hr = RegisterClassBase(rclsid, szDesc, rcProgID, rcIndProgID, rcCLSID, NumItems(rcCLSID))))
- return (hr);
-
- WCHAR *szServerType = bInprocServer ? W("InprocServer32") : W("LocalServer32");
-
- // Set the server path.
- SetKeyAndValue(rcCLSID, szServerType , szModule);
-
- // Add the threading model information.
- VERIFY(_snwprintf_s(rcInproc, _countof(rcInproc), _TRUNCATE, W("%s\\%s"), rcCLSID, szServerType));
-
- SetRegValue(rcInproc, W("ThreadingModel"), szThreadingModel);
- return (S_OK);
-}
-
-
-
-//*****************************************************************************
-// Register the basics for a in proc server.
-//*****************************************************************************
-HRESULT REGUTIL::RegisterClassBase( // Return code.
- REFCLSID rclsid, // Class ID we are registering.
- LPCTSTR szDesc, // Class description.
- LPCTSTR szProgID, // Class prog ID.
- LPCTSTR szIndepProgID, // Class version independant prog ID.
- __out_ecount(cchOutCLSID) LPTSTR szOutCLSID, // CLSID formatted in character form.
- DWORD cchOutCLSID) // Out CLS ID buffer size
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- TCHAR szID[64]; // The class ID to register.
-
- // Create some base key strings.
- GuidToLPWSTR(rclsid, szID, NumItems(szID));
-
- size_t nLen = _tcslen(_T("CLSID\\")) + _tcslen( szID) + 1;
- if( cchOutCLSID < nLen )
- return E_INVALIDARG;
-
- _tcscpy_s(szOutCLSID, cchOutCLSID, W("CLSID\\"));
- _tcscat_s(szOutCLSID, cchOutCLSID, szID);
-
- // Create ProgID keys.
- SetKeyAndValue(szProgID, NULL, szDesc);
- SetKeyAndValue(szProgID, W("CLSID"), szID);
-
- // Create VersionIndependentProgID keys.
- SetKeyAndValue(szIndepProgID, NULL, szDesc);
- SetKeyAndValue(szIndepProgID, W("CurVer"), szProgID);
- SetKeyAndValue(szIndepProgID, W("CLSID"), szID);
-
- // Create entries under CLSID.
- SetKeyAndValue(szOutCLSID, NULL, szDesc);
- SetKeyAndValue(szOutCLSID, W("ProgID"), szProgID);
- SetKeyAndValue(szOutCLSID, W("VersionIndependentProgID"), szIndepProgID);
- SetKeyAndValue(szOutCLSID, W("NotInsertable"), NULL);
- return (S_OK);
-}
-
-
-
-//*****************************************************************************
-// Unregister the basic information in the system registry for a given object
-// class.
-//*****************************************************************************
-HRESULT REGUTIL::UnregisterCOMClass( // Return code.
- REFCLSID rclsid, // Class ID we are registering.
- LPCTSTR szProgIDPrefix, // Prefix for progid.
- int iVersion, // Version # for progid.
- LPCTSTR szClassProgID, // Class progid.
- BOOL fExternal) // flag - External to mscoree.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- WCHAR rcCLSID[64]; // CLSID\\szID.
- WCHAR rcProgID[128]; // szProgIDPrefix.szClassProgID
- WCHAR rcIndProgID[128]; // rcProgID.iVersion
-
- // Format the prog ID values.
- VERIFY(_snwprintf_s(rcProgID, _countof(rcProgID), _TRUNCATE, W("%s.%s"), szProgIDPrefix, szClassProgID));
-
- VERIFY(_snwprintf_s(rcIndProgID, _countof(rcIndProgID), _TRUNCATE, W("%s.%d"), rcProgID, iVersion));
-
- UnregisterClassBase(rclsid, rcProgID, rcIndProgID, rcCLSID, NumItems(rcCLSID));
- DeleteKey(rcCLSID, W("InprocServer32"));
- if (fExternal){
- DeleteKey(rcCLSID, W("Server"));
- DeleteKey(rcCLSID, W("Version"));
- }
- GuidToLPWSTR(rclsid, rcCLSID, NumItems(rcCLSID));
- DeleteKey(W("CLSID"), rcCLSID);
- return (S_OK);
-}
-
-
-//*****************************************************************************
-// Unregister the basic information in the system registry for a given object
-// class.
-// NOTE: This is the non-side-by-side execution version.
-//*****************************************************************************
-HRESULT REGUTIL::UnregisterCOMClass( // Return code.
- REFCLSID rclsid, // Class ID we are registering.
- LPCTSTR szProgIDPrefix, // Prefix for progid.
- int iVersion, // Version # for progid.
- LPCTSTR szClassProgID) // Class progid.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- WCHAR rcCLSID[64]; // CLSID\\szID.
- WCHAR rcProgID[128]; // szProgIDPrefix.szClassProgID
- WCHAR rcIndProgID[128]; // rcProgID.iVersion
-
- // Format the prog ID values.
- VERIFY(_snwprintf_s(rcProgID, _countof(rcProgID), _TRUNCATE, W("%s.%s"), szProgIDPrefix, szClassProgID));
-
- VERIFY(_snwprintf_s(rcIndProgID, _countof(rcIndProgID), _TRUNCATE, W("%s.%d"), rcProgID, iVersion));
-
- UnregisterClassBase(rclsid, rcProgID, rcIndProgID, rcCLSID, NumItems(rcCLSID));
- DeleteKey(rcCLSID, W("InprocServer32"));
- DeleteKey(rcCLSID, W("LocalServer32"));
-
- GuidToLPWSTR(rclsid, rcCLSID, NumItems(rcCLSID));
- DeleteKey(W("CLSID"), rcCLSID);
- return (S_OK);
-}
-
-
-//*****************************************************************************
-// Delete the basic settings for an inproc server.
-//*****************************************************************************
-HRESULT REGUTIL::UnregisterClassBase( // Return code.
- REFCLSID rclsid, // Class ID we are registering.
- LPCTSTR szProgID, // Class prog ID.
- LPCTSTR szIndepProgID, // Class version independant prog ID.
- __out_ecount(cchOutCLSID) LPTSTR szOutCLSID, // Return formatted class ID here.
- DWORD cchOutCLSID) // Out CLS ID buffer size
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- TCHAR szID[64]; // The class ID to register.
-
- // Create some base key strings.
- GuidToLPWSTR(rclsid, szID, NumItems(szID));
- size_t nLen = _tcslen(_T("CLSID\\")) + _tcslen( szID) + 1;
- if( cchOutCLSID < nLen )
- return E_INVALIDARG;
-
- _tcscpy_s(szOutCLSID, cchOutCLSID, W("CLSID\\"));
- _tcscat_s(szOutCLSID, cchOutCLSID, szID);
-
- // Delete the version independant prog ID settings.
- DeleteKey(szIndepProgID, W("CurVer"));
- DeleteKey(szIndepProgID, W("CLSID"));
- WszRegDeleteKey(HKEY_CLASSES_ROOT, szIndepProgID);
-
- // Delete the prog ID settings.
- DeleteKey(szProgID, W("CLSID"));
- WszRegDeleteKey(HKEY_CLASSES_ROOT, szProgID);
-
- // Delete the class ID settings.
- DeleteKey(szOutCLSID, W("ProgID"));
- DeleteKey(szOutCLSID, W("VersionIndependentProgID"));
- DeleteKey(szOutCLSID, W("NotInsertable"));
- WszRegDeleteKey(HKEY_CLASSES_ROOT, szOutCLSID);
- return (S_OK);
-}
-
-
-//*****************************************************************************
-// Register a type library.
-//*****************************************************************************
-HRESULT REGUTIL::RegisterTypeLib( // Return code.
- REFGUID rtlbid, // TypeLib ID we are registering.
- int iVersion, // Typelib version.
- LPCTSTR szDesc, // TypeLib description.
- LPCTSTR szModule) // Path to the typelib.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- WCHAR szID[64]; // The typelib ID to register.
- WCHAR szTLBID[256]; // TypeLib\\szID.
- WCHAR szHelpDir[_MAX_PATH];
- WCHAR szDrive[_MAX_DRIVE] = {0};
- WCHAR szDir[_MAX_DIR] = {0};
- WCHAR szVersion[64];
- LPWSTR szTmp;
-
- // Create some base key strings.
- GuidToLPWSTR(rtlbid, szID, NumItems(szID));
-
- _tcscpy_s(szTLBID, _countof(szTLBID), W("TypeLib\\"));
- _tcscat_s(szTLBID, _countof(szTLBID), szID);
-
- VERIFY(_snwprintf_s(szVersion, _countof(szVersion), _TRUNCATE, W("%d.0"), iVersion));
-
- // Create Typelib keys.
- SetKeyAndValue(szTLBID, NULL, NULL);
- SetKeyAndValue(szTLBID, szVersion, szDesc);
- _tcscat_s(szTLBID, _countof(szTLBID), W("\\"));
- _tcscat_s(szTLBID, _countof(szTLBID), szVersion);
- SetKeyAndValue(szTLBID, W("0"), NULL);
- SetKeyAndValue(szTLBID, W("0\\win32"), szModule);
- SetKeyAndValue(szTLBID, W("FLAGS"), W("0"));
- SplitPath(szModule, szDrive, _MAX_DRIVE, szDir, _MAX_DIR, NULL, 0, NULL, 0);
- _tcscpy_s(szHelpDir, _countof(szHelpDir), szDrive);
- if ((szTmp = CharPrev(szDir, szDir + Wszlstrlen(szDir))) != NULL)
- *szTmp = '\0';
- _tcscat_s(szHelpDir, _countof(szHelpDir), szDir);
- SetKeyAndValue(szTLBID, W("HELPDIR"), szHelpDir);
- return (S_OK);
-}
-
-
-//*****************************************************************************
-// Remove the registry keys for a type library.
-//*****************************************************************************
-HRESULT REGUTIL::UnregisterTypeLib( // Return code.
- REFGUID rtlbid, // TypeLib ID we are registering.
- int iVersion) // Typelib version.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- WCHAR szID[64]; // The typelib ID to register.
- WCHAR szTLBID[256]; // TypeLib\\szID.
- WCHAR szTLBVersion[256]; // TypeLib\\szID\\szVersion
- WCHAR szVersion[64];
-
- // Create some base key strings.
- GuidToLPWSTR(rtlbid, szID, NumItems(szID));
-
- VERIFY(_snwprintf_s(szVersion, _countof(szVersion), _TRUNCATE, W("%d.0"), iVersion));
-
- _tcscpy_s(szTLBID, _countof(szTLBID), W("TypeLib\\"));
- _tcscat_s(szTLBID, _countof(szTLBID), szID);
- _tcscpy_s(szTLBVersion, _countof(szTLBVersion), szTLBID);
- _tcscat_s(szTLBVersion, _countof(szTLBVersion), W("\\"));
- _tcscat_s(szTLBVersion, _countof(szTLBVersion), szVersion);
-
- // Delete Typelib keys.
- DeleteKey(szTLBVersion, W("HELPDIR"));
- DeleteKey(szTLBVersion, W("FLAGS"));
- DeleteKey(szTLBVersion, W("0\\win32"));
- DeleteKey(szTLBVersion, W("0"));
- DeleteKey(szTLBID, szVersion);
- WszRegDeleteKey(HKEY_CLASSES_ROOT, szTLBID);
- return (0);
-}
-
-#endif // !FEATURE_CORECLR
//
return i;
}
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- ////////////////////////////////////////////////////////////////////////////
- //
- // LoadSortModuleAndInvariant()
- //
- // Attempts to load the given dll. If that is successful, attempts to
- // load the invariant data. If that is successful, returns the module handle
- // and the addresses of the SortGetHandle function and SortCloseHandle function
- //
- // failure is indicated by returning NULL for the module handle and the
- // function addresses
- //
- ////////////////////////////////////////////////////////////////////////////
-
- HMODULE LoadSortModuleAndInvariant(
- __in LPCWSTR sDllName,
- __in DWORD dwVersion,
- __out SORTGETHANDLE* ppGetHandle,
- __out SORTCLOSEHANDLE* ppCloseHandle
- )
- {
- *ppGetHandle = NULL;
- *ppCloseHandle = NULL;
- HMODULE hSort;
-
- if(FAILED(UtilCode::LoadLibraryShim(sDllName, NULL, NULL, &hSort)))
- {
- return NULL;
- }
-
- SORTGETHANDLE pGetHandle = (SORTGETHANDLE)GetProcAddress(hSort, "SortGetHandle");
- SORTCLOSEHANDLE pCloseHandle = (SORTCLOSEHANDLE)GetProcAddress(hSort, "SortCloseHandle");
-
- // If we didn't load the procs, then remember that
- if (pCloseHandle == NULL || pGetHandle == NULL)
- {
- ::FreeLibrary(hSort);
- return NULL;
- }
-
- // Verify that the data file's available
- NLSVERSIONINFO sortVersion;
- sortVersion.dwNLSVersionInfoSize = sizeof(NLSVERSIONINFO);
- sortVersion.dwNLSVersion = dwVersion;
- sortVersion.dwDefinedVersion = dwVersion;
-
- // Invariant must be there and is kinda common, so we'll just get it
- PSORTHANDLE pSort = pGetHandle(W(""), &sortVersion, NULL);
- if (!pSort)
- {
- // Yikes, invariant failed, forget about it.
- ::FreeLibrary(hSort);
- return NULL;
- }
-
- // Since we found it, may as well remember it.
- const SORTHANDLE * const pSortInHash = InsertSortHashNode(pSort);
-
- // If we got a different one back then free the one we added
- if (pSortInHash != pSort && pSortInHash)
- {
- // We got a different one from the hash (someone beat us to the cache)
- // so use that and discard the new one.
- pCloseHandle(pSort);
- }
-
- *ppGetHandle = pGetHandle;
- *ppCloseHandle = pCloseHandle;
- return hSort;
- }
-
- // Attempts to load a Sort DLL. If this fails, the values of the __out parameters are unchanged.
- __success(return)
- BOOL LoadSortDllAndPublish(
- __in LPCWSTR sDllName,
- __in DWORD dwVersion,
- __out __encoded_pointer SORTGETHANDLE* ppGetHandle,
- __out __encoded_pointer SORTCLOSEHANDLE* ppCloseHandle,
- __out HMODULE* phSortDll)
- {
- HMODULE hSortDll;
- SORTGETHANDLE pGetHandle;
- SORTCLOSEHANDLE pCloseHandle;
-
- hSortDll = LoadSortModuleAndInvariant(sDllName, dwVersion, &pGetHandle, &pCloseHandle);
-
- if(hSortDll != NULL) {
- *phSortDll = hSortDll;
- *ppGetHandle = (SORTGETHANDLE)EncodePointer(pGetHandle);
- *ppCloseHandle = (SORTCLOSEHANDLE)EncodePointer(pCloseHandle);
- return TRUE;
- }
-
- return FALSE;
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetSortGetHandle()
- //
- // Get the SortGetHandle() function for the proper dll version.
- //
- ////////////////////////////////////////////////////////////////////////////
- SORTGETHANDLE GetSortGetHandle(__in DWORD dwVersion)
- {
- if(dwVersion == SORT_VERSION_DEFAULT)
- {
- // If we haven't tried to load the module/proc before do so now
- if (g_hSortDefault == (HMODULE)-1)
- {
- LoadSortDllAndPublish(SORT_DEFAULT_DLL_NAME, SORT_VERSION_DEFAULT, &g_pDefaultGetHandle, &g_pDefaultCloseHandle, &g_hSortDefault);
- }
-
- // This check is necessary because the LoadSortDllAndPublish call may have failed since some platforms
- // won't have nlssorting.dll (e.g. Windows 8 and above).
- if (g_hSortDefault != (HMODULE)-1)
- {
- return (SORTGETHANDLE)DecodePointer(g_pDefaultGetHandle);
- }
- }
-
- HMODULE* pHSortModule;
- SORTGETHANDLE* ppGetHandle;
- SORTCLOSEHANDLE* ppCloseHandle;
-
- if(dwVersion == SORT_VERSION_V4)
- {
- ppGetHandle = &g_pV4GetHandle;
- ppCloseHandle = &g_pV4CloseHandle;
- pHSortModule = &g_hSortCompatV4;
- }
- else if(dwVersion == SORT_VERSION_WHIDBEY)
- {
- ppGetHandle = &g_pV2GetHandle;
- ppCloseHandle = &g_pV2CloseHandle;
- pHSortModule = &g_hSortCompatV2;
- }
- else
- {
- // Unsupported sorting version.
- return NULL;
- }
-
- if(*pHSortModule == (HMODULE) -1)
- {
- // get module name - the module name should be "Sort"+dwVersion.ToString("x8")+".dll"
- WCHAR moduleName[] = W("Sort00000000.dll");
- // replace the "00000000" with the hexadecimal of dwVersion
- LPCWSTR hex = W("0123456789abcdef");
- WCHAR* p = &moduleName[4+8]; // position at end of number part of dll name
-
- unsigned int value = dwVersion;
-
- while (value != 0 && p != moduleName) {
- int digit = value & 0xF;
- *--p = hex[digit];
- value >>= 4;
- }
-
- if(!LoadSortDllAndPublish(&moduleName[0], dwVersion, ppGetHandle, ppCloseHandle, pHSortModule))
- {
- // We failed to load a versioned sort dll, try to fall back to the current version.
- // If we haven't tried to load the module/proc before do so now
- if (g_hSortDefault == (HMODULE)-1)
- {
- LoadSortDllAndPublish(SORT_DEFAULT_DLL_NAME, SORT_VERSION_DEFAULT, &g_pDefaultGetHandle, &g_pDefaultCloseHandle, &g_hSortDefault);
- }
-
- *pHSortModule = g_hSortDefault;
- *ppCloseHandle = g_pDefaultCloseHandle;
- *ppGetHandle = g_pDefaultGetHandle;
- }
- }
-
- // At this point, we've either loaded a sorting dll or we've exausted all options.
- if(*pHSortModule == (HMODULE) -1)
- {
- // Couldn't find anything, give up.
- return NULL;
- }
- else
- {
- return (SORTGETHANDLE)DecodePointer(*ppGetHandle);
- }
-
- // Unknown version requested
- return NULL;
- }
-
- void DoSortCloseHandle(__in DWORD dwVersion, __in PSORTHANDLE pSort)
- {
- if (dwVersion == SORT_VERSION_DEFAULT)
- {
- SORTCLOSEHANDLE pDefaultCloseHandle = (SORTCLOSEHANDLE)DecodePointer(g_pDefaultCloseHandle);
- if(pDefaultCloseHandle != NULL)
- {
- (pDefaultCloseHandle)(pSort);
- return;
- }
- }
-
- if (dwVersion == SORT_VERSION_V4)
- {
- SORTCLOSEHANDLE pV4CloseHandle = (SORTCLOSEHANDLE)DecodePointer(g_pV4CloseHandle);
- if(pV4CloseHandle != NULL)
- {
- (pV4CloseHandle)(pSort);
- return;
- }
- }
-
-
- if (dwVersion == SORT_VERSION_WHIDBEY)
- {
- SORTCLOSEHANDLE pV2CloseHandle = (SORTCLOSEHANDLE)DecodePointer(g_pV2CloseHandle);
- if(pV2CloseHandle != NULL)
- {
- (pV2CloseHandle)(pSort);
- return;
- }
- }
- }
-
-#else // !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
SORTGETHANDLE GetSortGetHandle(__in DWORD dwVersion)
{
{
}
-#endif // !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////
DWORD SortNLSVersion()
{
-#ifdef FEATURE_CORECLR
return SORT_VERSION_DEFAULT;
-#else
- static bool sortNLSVersionConfigChecked = false;
- static DWORD sortNLSVersion = SORT_VERSION_DEFAULT;
-
- if(!sortNLSVersionConfigChecked)
- {
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return false);
- sortNLSVersion = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CompatSortNLSVersion);
- if(sortNLSVersion == 0)
- {
- sortNLSVersion = SORT_VERSION_DEFAULT;
- }
- END_SO_INTOLERANT_CODE;
-
- sortNLSVersionConfigChecked = true;
- }
- return sortNLSVersion;
-#endif // !FEATURE_CORECLR
}
////////////////////////////////////////////////////////////////////////////
}
}
-#if defined(_TARGET_X86_) && defined(FEATURE_CORECLR)
+#if defined(_TARGET_X86_)
/****************************************************************************
* ClrCaptureContext *
*-------------------*
STATIC_CONTRACT_LEAF;
STATIC_CONTRACT_SUPPORTS_DAC;
-#if defined(FEATURE_EVENT_TRACE) && !defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE)
- return ((Microsoft_Windows_DotNETRuntimeStressHandle != 0) &&
- (ETW_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_STRESS_PROVIDER_Context, (UCHAR)level, facility) != 0));
-#else
return FALSE;
-#endif
}
BOOL StressLog::ETWLogOn(unsigned facility, unsigned level)
}
// Stress Log ETW feature available only on the desktop versions of the runtime
-#if !defined(FEATURE_CORECLR)
- // The previous LogMsg call could have modified the Args, so we need to reset it
- if(InlinedETWLogOn(facility, level))
- {
-#define MAX_STRESSLOG_DATA_ETW_LENGTH 256
- CHAR logMessage[MAX_STRESSLOG_DATA_ETW_LENGTH];
-
- va_start(Args, format);
- ULONG messageLength = (USHORT)_vsnprintf_s(logMessage, COUNTOF(logMessage), MAX_STRESSLOG_DATA_ETW_LENGTH-1, format, Args);
- va_end(Args);
-
- if(messageLength >= 0 &&
- messageLength < MAX_STRESSLOG_DATA_ETW_LENGTH) // this condition has been added to make prefast happy
- {
- logMessage[messageLength] = 0;
- }
- messageLength++;
- logMessage[MAX_STRESSLOG_DATA_ETW_LENGTH-1] = 0;
- FireEtwStressLogEvent_V1((UINT32)facility, (UCHAR)level, logMessage, GetClrInstanceId());
-#undef MAX_STRESSLOG_DATA_ETW_LENGTH
- }
-#endif // !FEATURE_CORECLR
#endif //!DACCESS_COMPILE
}
#include "cor.h"
#include "corinfo.h"
-#ifndef FEATURE_CORECLR
-#include "metahost.h"
-#endif // !FEATURE_CORECLR
const char g_RTMVersion[]= "v1.0.3705";
return TRUE;
}
-#ifndef FEATURE_CORECLR
-// Current users for FileLock are ngen and ngen service
-
-FileLockHolder::FileLockHolder()
-{
- _hLock = INVALID_HANDLE_VALUE;
-}
-
-FileLockHolder::~FileLockHolder()
-{
- Release();
-}
-
-// the amount of time we want to wait
-#define FILE_LOCK_RETRY_TIME 100
-
-void FileLockHolder::Acquire(LPCWSTR lockName, HANDLE hInterrupt, BOOL* pInterrupted)
-{
- WRAPPER_NO_CONTRACT;
-
- DWORD dwErr = 0;
- DWORD dwAccessDeniedRetry = 0;
- const DWORD MAX_ACCESS_DENIED_RETRIES = 10;
-
- if (pInterrupted)
- {
- *pInterrupted = FALSE;
- }
-
- _ASSERTE(_hLock == INVALID_HANDLE_VALUE);
-
- for (;;) {
- _hLock = WszCreateFile(lockName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL);
- if (_hLock != INVALID_HANDLE_VALUE) {
- return;
- }
-
- dwErr = GetLastError();
- // Logically we should only expect ERROR_SHARING_VIOLATION, but Windows can also return
- // ERROR_ACCESS_DENIED for underlying NtStatus DELETE_PENDING. That happens when another process
- // (gacutil.exe or indexer) have the file opened. Unfortunately there is no public API that would
- // allow us to detect this NtStatus and distinguish it from 'real' access denied (candidates are
- // RtlGetLastNtStatus that is not documented on MSDN and NtCreateFile that is internal and can change
- // at any time), so we retry on access denied, but only for a limited number of times.
- if (dwErr == ERROR_SHARING_VIOLATION ||
- (dwErr == ERROR_ACCESS_DENIED && ++dwAccessDeniedRetry <= MAX_ACCESS_DENIED_RETRIES))
- {
- // Somebody is holding the lock. Let's sleep, and come back again.
- if (hInterrupt)
- {
- _ASSERTE(pInterrupted &&
- "If you can be interrupted, you better want to know if you actually were interrupted");
- if (WaitForSingleObject(hInterrupt, FILE_LOCK_RETRY_TIME) == WAIT_OBJECT_0)
- {
- if (pInterrupted)
- {
- *pInterrupted = TRUE;
- }
-
- // We've been interrupted, so return without acquiring
- return;
- }
- }
- else
- {
- ClrSleepEx(FILE_LOCK_RETRY_TIME, FALSE);
- }
- }
- else {
- ThrowHR(HRESULT_FROM_WIN32(dwErr));
- }
- }
-}
-
-
-HRESULT FileLockHolder::AcquireNoThrow(LPCWSTR lockName, HANDLE hInterrupt, BOOL* pInterrupted)
-{
- HRESULT hr = S_OK;
-
- EX_TRY
- {
- Acquire(lockName, hInterrupt, pInterrupted);
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-
-BOOL FileLockHolder::IsTaken(LPCWSTR lockName)
-{
-
- // We don't want to do an acquire the lock to know if its taken, so we want to see if the file
- // exists. However, in situations like unplugging a machine, a DELETE_ON_CLOSE still leaves the file
- // around. We try to delete it here. If the lock is acquired, DeleteFile will fail, as the file is
- // not opened with SHARE_DELETE.
- WszDeleteFile(lockName);
-
- return FileExists(lockName);
-}
-
-void FileLockHolder::Release()
-{
- if (_hLock != INVALID_HANDLE_VALUE) {
- CloseHandle(_hLock);
- _hLock = INVALID_HANDLE_VALUE;
- }
-}
-#endif // FEATURE_CORECLR
//======================================================================
// This function returns true, if it can determine that the instruction pointer
BOOL IsV2RuntimeLoaded(void)
{
-#ifndef FEATURE_CORECLR
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- CANNOT_TAKE_LOCK;
- }
- CONTRACTL_END;
-
- ReleaseHolder<ICLRMetaHost> pMetaHost(NULL);
- ReleaseHolder<IEnumUnknown> pEnum(NULL);
- ReleaseHolder<IUnknown> pUnk(NULL);
- ReleaseHolder<ICLRRuntimeInfo> pRuntime(NULL);
- HRESULT hr;
-
- HModuleHolder hModule = WszLoadLibrary(MSCOREE_SHIM_W);
- if (hModule == NULL)
- return FALSE;
-
- CLRCreateInstanceFnPtr pfnCLRCreateInstance = (CLRCreateInstanceFnPtr)::GetProcAddress(hModule, "CLRCreateInstance");
- if (pfnCLRCreateInstance == NULL)
- return FALSE;
-
- hr = (*pfnCLRCreateInstance)(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID *)&pMetaHost);
- if (FAILED(hr))
- return FALSE;
-
- hr = pMetaHost->EnumerateLoadedRuntimes(GetCurrentProcess(), &pEnum);
- if (FAILED(hr))
- return FALSE;
-
- while (pEnum->Next(1, &pUnk, NULL) == S_OK)
- {
- hr = pUnk->QueryInterface(IID_ICLRRuntimeInfo, (void **)&pRuntime);
- if (FAILED(hr))
- continue;
-
- WCHAR wszVersion[30];
- DWORD cchVersion = _countof(wszVersion);
- hr = pRuntime->GetVersionString(wszVersion, &cchVersion);
- if (FAILED(hr))
- continue;
-
- // Is it a V2 runtime?
- if ((cchVersion < 3) ||
- ((wszVersion[0] != W('v')) && (wszVersion[0] != W('V'))) ||
- (wszVersion[1] != W('2')) ||
- (wszVersion[2] != W('.')))
- continue;
-
- return TRUE;
- }
-#endif // FEATURE_CORECLR
return FALSE;
}
-#if !defined(FEATURE_CORECLR) && !defined(SELF_NO_HOST) && !defined(FEATURE_UTILCODE_NO_DEPENDENCIES)
-
-namespace UtilCode
-{
-
-#pragma warning(push)
-#pragma warning(disable:4996) // For use of deprecated LoadLibraryShim
-
- // When a NULL version is passed to LoadLibraryShim, this told the shim to bind the already-loaded
- // runtime or to the latest runtime. In hosted environments, we already know a runtime (or two) is
- // loaded, and since we are no longer guaranteed that a call to mscoree!LoadLibraryShim with a NULL
- // version will return the correct runtime, this code uses the ClrCallbacks infrastructure
- // available to get the ICLRRuntimeInfo for the runtime in which this code is hosted, and then
- // calls ICLRRuntimeInfo::LoadLibrary to make sure that the load occurs within the context of the
- // correct runtime.
- HRESULT LoadLibraryShim(LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE *phModDll)
- {
- HRESULT hr = S_OK;
-
- if (szVersion != NULL)
- { // If a version is provided, then we just fall back to the legacy function to allow
- // it to construct the explicit path and load from that location.
- //@TODO: Can we verify that all callers of LoadLibraryShim in hosted environments always pass null and eliminate this code?
- return ::LoadLibraryShim(szDllName, szVersion, pvReserved, phModDll);
- }
-
- //
- // szVersion is NULL, which means we should load the DLL from the hosted environment's directory.
- //
-
- typedef ICLRRuntimeInfo *GetCLRRuntime_t();
- GetCLRRuntime_t *pfnGetCLRRuntime =
- reinterpret_cast<GetCLRRuntime_t *>((*GetClrCallbacks().m_pfnGetCLRFunction)("GetCLRRuntime"));
- if (pfnGetCLRRuntime == NULL)
- return E_UNEXPECTED;
-
- ICLRRuntimeInfo* pRI = (*pfnGetCLRRuntime)();
- if (pRI == NULL)
- return E_UNEXPECTED;
-
- return pRI->LoadLibrary(szDllName, phModDll);
- }
-
-#pragma warning(pop)
-
-}
-
-#endif //!FEATURE_CORECLR && !SELF_NO_HOST && !FEATURE_UTILCODE_NO_DEPENDENCIES
namespace Clr
{
#include "commctrl.h"
#endif
-#if !defined(SELF_NO_HOST) && !defined(FEATURE_CORECLR)
-
-//
-// This should be used for runtime dialog box, because we assume the resource is from mscorrc.dll
-// For tools like ildasm or Shim which uses their own resource file, you need to define IDS_RTL in
-// their resource file and define a function like this and append the style returned from the function
-// to every calls to WszMessageBox.
-//
-UINT GetCLRMBRTLStyle()
-{
- WRAPPER_NO_CONTRACT;
-
- UINT mbStyle = 0;
- WCHAR buff[MAX_LONGPATH];
- if(SUCCEEDED(UtilLoadStringRC(IDS_RTL, buff, MAX_LONGPATH, true))) {
- if(wcscmp(buff, W("RTL_True")) == 0) {
- mbStyle = 0x00080000 |0x00100000; // MB_RIGHT || MB_RTLREADING
- }
- }
- return mbStyle;
-}
-
-#endif //!defined(SELF_NO_HOST) && !defined(FEATURE_CORECLR)
BOOL ShouldDisplayMsgBoxOnCriticalFailure()
{
// in use. However, outside the CLR (SELF_NO_HOST) we can't assume we have resources and
// in CORECLR we can't even necessarily expect that our CLR callbacks have been initialized.
// This code path is used for ASSERT dialogs.
-#if !defined(SELF_NO_HOST) && !defined(FEATURE_CORECLR)
- uType |= GetCLRMBRTLStyle();
-#endif
result = MessageBoxImpl(hWnd, formattedMessage, formattedTitle, details, uType);
#include "clrprivtypecachewinrt.h"
-#ifndef FEATURE_CORECLR
-#include "nlsinfo.h"
-#endif
#ifdef FEATURE_RANDOMIZED_STRING_HASHING
#pragma warning(push)
void BaseDomain::Attach()
{
#ifdef FEATURE_RANDOMIZED_STRING_HASHING
-#ifdef FEATURE_CORECLR
// Randomized string hashing is on by default for String.GetHashCode in coreclr.
COMNlsHashProvider::s_NlsHashProvider.SetUseRandomHashing((CorHost2::GetStartupFlags() & STARTUP_DISABLE_RANDOMIZED_STRING_HASHING) == 0);
-#endif // FEATURE_CORECLR
#endif // FEATURE_RANDOMIZED_STRING_HASHING
m_SpecialStaticsCrst.Init(CrstSpecialStatics);
}
m_pDelayedLoaderAllocatorUnloadList = pLoaderAllocator;
}
-#ifdef FEATURE_CORECLR
void AppDomain::ShutdownNativeDllSearchDirectories()
{
LIMITED_METHOD_CONTRACT;
m_NativeDllSearchDirectories.Clear();
}
-#endif
void AppDomain::ReleaseDomainBoundInfo()
{
#ifndef CROSSGEN_COMPILE
if (!NingenEnabled())
{
-#ifndef FEATURE_CORECLR
- pDefaultDomain->InitializeHashing(NULL);
- pDefaultDomain->InitializeSorting(NULL);
-#endif // FEATURE_CORECLR
}
#endif // CROSSGEN_COMPILE
Volatile<LONG> g_fInExecuteMainMethod = 0;
#endif
-#ifndef FEATURE_CORECLR
-void SystemDomain::ExecuteMainMethod(HMODULE hMod, __in_opt LPWSTR path /*=NULL*/)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- PRECONDITION(CheckPointer(hMod, NULL_OK));
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
-#ifdef _DEBUG
- CounterHolder counter(&g_fInExecuteMainMethod);
-#endif
-
- Thread *pThread = GetThread();
- _ASSERTE(pThread);
-
- GCX_COOP();
-
- //
- // There is no EH protecting this transition!
- // This is generically ok in this method because if we throw out of here, it becomes unhandled anyway.
- //
- FrameWithCookie<ContextTransitionFrame> frame;
- pThread->EnterContextRestricted(SystemDomain::System()->DefaultDomain()->GetDefaultContext(), &frame);
- _ASSERTE(pThread->GetDomain());
-
- AppDomain *pDomain = GetAppDomain();
- _ASSERTE(pDomain);
-
- // Push this frame around loading the main assembly to ensure the
- // debugger can properly recognize any managed code that gets run
- // as "class initializaion" code.
- FrameWithCookie<DebuggerClassInitMarkFrame> __dcimf;
- {
- GCX_PREEMP();
-
- PEImageHolder pTempImage(PEImage::LoadImage(hMod));
-
- PEFileHolder pTempFile(PEFile::Open(pTempImage.Extract()));
-
- // Check for CustomAttributes - Set up the DefaultDomain and the main thread
- // Note that this has to be done before ExplicitBind() as it
- // affects the bind
- mdToken tkEntryPoint = pTempFile->GetEntryPointToken();
- // <TODO>@TODO: What if the entrypoint is in another file of the assembly?</TODO>
- ReleaseHolder<IMDInternalImport> scope(pTempFile->GetMDImportWithRef());
- // In theory, we should have a valid executable image and scope should never be NULL, but we've been
- // getting Watson failures for AVs here due to ISVs modifying image headers and some new OS loader
- // checks (see Dev10# 718530 and Windows 7# 615596)
- if (scope == NULL)
- {
- ThrowHR(COR_E_BADIMAGEFORMAT);
- }
-
-#ifdef FEATURE_COMINTEROP
- Thread::ApartmentState state = Thread::AS_Unknown;
-
- if((!IsNilToken(tkEntryPoint)) && (TypeFromToken(tkEntryPoint) == mdtMethodDef)) {
- if (scope->IsValidToken(tkEntryPoint))
- state = SystemDomain::GetEntryPointThreadAptState(scope, tkEntryPoint);
- else
- ThrowHR(COR_E_BADIMAGEFORMAT);
- }
-
- // If the entry point has an explicit thread apartment state, set it
- // before running the AppDomainManager initialization code.
- if (state == Thread::AS_InSTA || state == Thread::AS_InMTA)
- SystemDomain::SetThreadAptState(scope, state);
-#endif // FEATURE_COMINTEROP
-
- BOOL fSetGlobalSharePolicyUsingAttribute = FALSE;
-
- if((!IsNilToken(tkEntryPoint)) && (TypeFromToken(tkEntryPoint) == mdtMethodDef))
- {
- // The global share policy needs to be set before initializing default domain
- // so that it is in place for loading of appdomain manager.
- fSetGlobalSharePolicyUsingAttribute = SystemDomain::SetGlobalSharePolicyUsingAttribute(scope, tkEntryPoint);
- }
-
- // This can potentially run managed code.
- InitializeDefaultDomain(FALSE);
-
-#ifdef FEATURE_COMINTEROP
- // If we haven't set an explicit thread apartment state, set it after the
- // AppDomainManager has got a chance to go set it in InitializeNewDomain.
- if (state != Thread::AS_InSTA && state != Thread::AS_InMTA)
- SystemDomain::SetThreadAptState(scope, state);
-#endif // FEATURE_COMINTEROP
-
- if (fSetGlobalSharePolicyUsingAttribute)
- SystemDomain::System()->DefaultDomain()->SetupLoaderOptimization(g_dwGlobalSharePolicy);
-
- NewHolder<IPEFileSecurityDescriptor> pSecDesc(Security::CreatePEFileSecurityDescriptor(pDomain, pTempFile));
-
- {
- GCX_COOP();
- pSecDesc->Resolve();
- if (pSecDesc->AllowBindingRedirects())
- pDomain->TurnOnBindingRedirects();
- }
-
- PEAssemblyHolder pFile(pDomain->BindExplicitAssembly(hMod, TRUE));
-
- pDomain->m_pRootAssembly = GetAppDomain()->LoadAssembly(NULL, pFile, FILE_ACTIVE);
-
- {
- GCX_COOP();
-
- // Reuse the evidence that was generated for the PEFile for the assembly so we don't have to
- // regenerate evidence of the same type again if it is requested later.
- pDomain->m_pRootAssembly->GetSecurityDescriptor()->SetEvidenceFromPEFile(pSecDesc);
- }
-
- // If the AppDomainManager for the default domain was specified in the application config file then
- // we require that the assembly be trusted in order to set the manager
- if (pDomain->HasAppDomainManagerInfo() && pDomain->AppDomainManagerSetFromConfig())
- {
- Assembly *pEntryAssembly = pDomain->GetAppDomainManagerEntryAssembly();
- if (!pEntryAssembly->GetSecurityDescriptor()->AllowApplicationSpecifiedAppDomainManager())
- {
- COMPlusThrow(kTypeLoadException, IDS_E_UNTRUSTED_APPDOMAIN_MANAGER);
- }
- }
-
- if (CorCommandLine::m_pwszAppFullName == NULL) {
- StackSString friendlyName;
- StackSString assemblyPath = pFile->GetPath();
- SString::Iterator i = assemblyPath.End();
-
- if (PEAssembly::FindLastPathSeparator(assemblyPath, i)) {
- i++;
- friendlyName.Set(assemblyPath, i, assemblyPath.End());
- }
- else
- friendlyName.Set(assemblyPath);
-
- pDomain->SetFriendlyName(friendlyName, TRUE);
- }
- }
- __dcimf.Pop();
-
- {
- GCX_PREEMP();
-
- LOG((LF_CLASSLOADER | LF_CORDB,
- LL_INFO10,
- "Created domain for an executable at %p\n",
- (pDomain->m_pRootAssembly ? pDomain->m_pRootAssembly->Parent() : NULL)));
- TESTHOOKCALL(RuntimeStarted(RTS_CALLINGENTRYPOINT));
-
-#ifdef FEATURE_MULTICOREJIT
- pDomain->GetMulticoreJitManager().AutoStartProfile(pDomain);
-#endif
-
- pDomain->m_pRootAssembly->ExecuteMainMethod(NULL, TRUE /* waitForOtherThreads */);
- }
-
- pThread->ReturnToContext(&frame);
-
-#ifdef FEATURE_TESTHOOKS
- TESTHOOKCALL(LeftAppDomain(DefaultADID));
-#endif
-}
-#endif //!FEATURE_CORECLR
#ifdef FEATURE_CLICKONCE
void SystemDomain::ActivateApplication(int *pReturnValue)
#if defined(FEATURE_CLASSIC_COMINTEROP) && !defined(CROSSGEN_COMPILE)
-#ifdef FEATURE_CORECLR
MethodTable *AppDomain::LoadCOMClass(GUID clsid,
BOOL bLoadRecord/*=FALSE*/,
BOOL* pfAssemblyInReg/*=NULL*/)
// @CORESYSTODO: what to do here?
return NULL;
}
-#else // FEATURE_CORECLR
-
-static BOOL IsSameRuntimeVersion(ICLRRuntimeInfo *pInfo1, ICLRRuntimeInfo *pInfo2)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- WCHAR wszVersion1[_MAX_PATH];
- WCHAR wszVersion2[_MAX_PATH];
- DWORD cchVersion;
-
- cchVersion = COUNTOF(wszVersion1);
- IfFailThrow(pInfo1->GetVersionString(wszVersion1, &cchVersion));
-
- cchVersion = COUNTOF(wszVersion2);
- IfFailThrow(pInfo2->GetVersionString(wszVersion2, &cchVersion));
-
- return SString::_wcsicmp(wszVersion1, wszVersion2) == 0;
-}
-
-MethodTable *AppDomain::LoadCOMClass(GUID clsid,
- BOOL bLoadRecord/*=FALSE*/,
- BOOL* pfAssemblyInReg/*=NULL*/)
-{
- CONTRACT (MethodTable*)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
-
- MethodTable* pMT = NULL;
-
- NewArrayHolder<WCHAR> wszClassName = NULL;
- NewArrayHolder<WCHAR> wszAssemblyString = NULL;
- NewArrayHolder<WCHAR> wszCodeBaseString = NULL;
-
- DWORD cbAssembly = 0;
- DWORD cbCodeBase = 0;
- Assembly *pAssembly = NULL;
- BOOL fFromRegistry = FALSE;
- BOOL fRegFreePIA = FALSE;
-
- HRESULT hr = S_OK;
-
- if (pfAssemblyInReg != NULL)
- *pfAssemblyInReg = FALSE;
-
- // with sxs.dll help
- hr = FindShimInfoFromWin32(clsid, bLoadRecord, NULL, NULL, &wszClassName, &wszAssemblyString, &fRegFreePIA);
-
- if(FAILED(hr))
- {
- hr = FindShimInfoFromRegistry(clsid, bLoadRecord, VER_ASSEMBLYMAJORVERSION, VER_ASSEMBLYMINORVERSION,
- &wszClassName, &wszAssemblyString, &wszCodeBaseString);
- if (FAILED(hr))
- RETURN NULL;
-
- fFromRegistry = TRUE;
- }
-
- // Skip the GetRuntimeForManagedCOMObject check for value types since they cannot be activated and are
- // always used for wrapping existing instances coming from COM.
- if (!bLoadRecord)
- {
- // We will load the assembly only if it is a PIA or if unmanaged activation would load the currently running
- // runtime. Otherwise we return NULL which will result in using the default System.__ComObject type.
-
- // the type is a PIA type if mscoree.dll is not its inproc server dll or it was specified as <clrSurrogate> in the manifest
- BOOL fPIA = (fFromRegistry ? !Clr::Util::Com::CLSIDHasMscoreeAsInprocServer32(clsid) : fRegFreePIA);
- if (!fPIA)
- {
- // this isn't a PIA, so we must determine which runtime it would load
- ReleaseHolder<ICLRRuntimeHostInternal> pRuntimeHostInternal;
- IfFailThrow(g_pCLRRuntime->GetInterface(CLSID_CLRRuntimeHostInternal,
- IID_ICLRRuntimeHostInternal,
- &pRuntimeHostInternal));
-
- // we call the shim to see which runtime would this be activated in
- ReleaseHolder<ICLRRuntimeInfo> pRuntimeInfo;
- if (FAILED(pRuntimeHostInternal->GetRuntimeForManagedCOMObject(clsid, IID_ICLRRuntimeInfo, &pRuntimeInfo)))
- {
- // the requested runtime is not loadable - don't load the assembly
- RETURN NULL;
- }
-
- if (!IsSameRuntimeVersion(g_pCLRRuntime, pRuntimeInfo))
- {
- // the requested runtime is different from this runtime - don't load the assembly
- RETURN NULL;
- }
- }
- }
-
- if (pfAssemblyInReg != NULL)
- *pfAssemblyInReg = TRUE;
-
- if (wszAssemblyString != NULL) {
- pAssembly = LoadAssemblyHelper(wszAssemblyString, wszCodeBaseString);
- pMT = TypeName::GetTypeFromAssembly(wszClassName, pAssembly).GetMethodTable();
- if (!pMT)
- goto ErrExit;
- }
-
- if (pMT == NULL) {
- ErrExit:
- // Convert the GUID to its string representation.
- WCHAR szClsid[64];
- if (GuidToLPWSTR(clsid, szClsid, NumItems(szClsid)) == 0)
- szClsid[0] = 0;
-
- // Throw an exception indicating we failed to load the type with
- // the requested CLSID.
- COMPlusThrow(kTypeLoadException, IDS_CLASSLOAD_NOCLSIDREG, szClsid);
- }
-
- RETURN pMT;
-}
-
-#endif // FEATURE_CORECLR
#endif // FEATURE_CLASSIC_COMINTEROP && !CROSSGEN_COMPILE
CLASS__ASSEMBLY,
CLASS__TYPE_DELEGATOR,
CLASS__RUNTIME_HELPERS,
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
- CLASS__ITYPE,
- CLASS__IASSEMBLY,
- CLASS__IMETHODBASE,
- CLASS__IMETHODINFO,
- CLASS__ICONSTRUCTORINFO,
- CLASS__IFIELDINFO,
- CLASS__IPROPERTYINFO,
- CLASS__IEVENTINFO,
- CLASS__IAPPDOMAIN,
-#endif // FEATURE_COMINTEROP && !FEATURE_CORECLR
CLASS__LAZY_INITIALIZER,
CLASS__DYNAMICMETHOD,
CLASS__DELEGATE,
m_pUnloadRequestThread = NULL;
m_ADUnloadSink=NULL;
-#ifndef FEATURE_CORECLR
- m_bUseOsSorting = RunningOnWin8();
- m_sortVersion = DEFAULT_SORT_VERSION;
- m_pCustomSortLibrary = NULL;
-#if _DEBUG
- m_bSortingInitialized = FALSE;
-#endif // _DEBUG
- m_pNlsHashProvider = NULL;
-#endif //!FEATURE_CORECLR
// Initialize Shared state. Assemblies are loaded
// into each domain by default.
if(!g_fEEInit)
Terminate();
-#ifndef FEATURE_CORECLR
- if (m_pCustomSortLibrary)
- delete m_pCustomSortLibrary;
-
- if (m_pNlsHashProvider)
- delete m_pNlsHashProvider;
-#endif
#ifdef FEATURE_REMOTING
}
ShutdownAssemblies();
-#ifdef FEATURE_CORECLR
ShutdownNativeDllSearchDirectories();
-#endif
if (m_pRefClassFactHash)
{
return ref;
}
-#ifndef FEATURE_CORECLR
-void AppDomain::InitializeSorting(OBJECTREF* ppAppdomainSetup)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- THROWS;
- GC_NOTRIGGER;
- PRECONDITION(ppAppdomainSetup == NULL || IsProtectedByGCFrame(ppAppdomainSetup));
- }
- CONTRACTL_END;
-
- DWORD sortVersionFromConfig = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CompatSortNLSVersion);
-
- if(sortVersionFromConfig != 0)
- {
- m_bUseOsSorting = FALSE;
- m_sortVersion = sortVersionFromConfig;
- }
-
- if(ppAppdomainSetup != NULL)
- {
- APPDOMAINSETUPREF adSetup = (APPDOMAINSETUPREF) *ppAppdomainSetup;
- APPDOMAINSORTINGSETUPINFOREF sortingSetup = adSetup->GetAppDomainSortingSetupInfo();
-
- if(sortingSetup != NULL)
- {
- if(sortingSetup->UseV2LegacySorting() || sortingSetup->UseV4LegacySorting())
- {
-
- m_bUseOsSorting = FALSE;
-
- if(sortingSetup->UseV2LegacySorting())
- {
- m_sortVersion = SORT_VERSION_WHIDBEY;
- }
-
- if(sortingSetup->UseV4LegacySorting())
- {
- m_sortVersion = SORT_VERSION_V4;
- }
- }
- else if(sortingSetup->GetPFNIsNLSDefinedString() != NULL
- && sortingSetup->GetPFNCompareStringEx() != NULL
- && sortingSetup->GetPFNLCMapStringEx() != NULL
- && sortingSetup->GetPFNFindNLSStringEx() != NULL
- && sortingSetup->GetPFNCompareStringOrdinal() != NULL
- && sortingSetup->GetPFNGetNLSVersionEx() != NULL
- && sortingSetup->GetPFNFindStringOrdinal() != NULL)
- {
- m_pCustomSortLibrary = new COMNlsCustomSortLibrary;
- m_pCustomSortLibrary->pIsNLSDefinedString = (PFN_IS_NLS_DEFINED_STRING) sortingSetup->GetPFNIsNLSDefinedString();
- m_pCustomSortLibrary->pCompareStringEx = (PFN_COMPARE_STRING_EX) sortingSetup->GetPFNCompareStringEx();
- m_pCustomSortLibrary->pLCMapStringEx = (PFN_LC_MAP_STRING_EX) sortingSetup->GetPFNLCMapStringEx();
- m_pCustomSortLibrary->pFindNLSStringEx = (PFN_FIND_NLS_STRING_EX) sortingSetup->GetPFNFindNLSStringEx();
- m_pCustomSortLibrary->pCompareStringOrdinal = (PFN_COMPARE_STRING_ORDINAL) sortingSetup->GetPFNCompareStringOrdinal();
- m_pCustomSortLibrary->pGetNLSVersionEx = (PFN_GET_NLS_VERSION_EX) sortingSetup->GetPFNGetNLSVersionEx();
- m_pCustomSortLibrary->pFindStringOrdinal = (PFN_FIND_STRING_ORDINAL) sortingSetup->GetPFNFindStringOrdinal();
- }
- }
- }
-
- if(m_bUseOsSorting == FALSE && m_sortVersion == DEFAULT_SORT_VERSION)
- {
- // If we are using the legacy sorting dlls, the default version for sorting is SORT_VERSION_V4. Note that
- // we don't expect this to change in the future (even when V5 or V6 of the runtime comes out).
- m_sortVersion = SORT_VERSION_V4;
- }
-
- if(RunningOnWin8() && m_bUseOsSorting == FALSE)
- {
- // We need to ensure that the versioned sort DLL could load so we don't crash later. This ensures we have
- // the same behavior as Windows 7, where even if we couldn't load the correct versioned sort dll, we would
- // provide the default sorting behavior.
- INT_PTR sortOrigin;
- if(COMNlsInfo::InternalInitVersionedSortHandle(W(""), &sortOrigin, m_sortVersion) == NULL)
- {
- LOG((LF_APPDOMAIN, LL_WARNING, "AppDomain::InitializeSorting failed to load legacy sort DLL for AppDomain.\n"));
- // We couldn't load a sort DLL. Fall back to default sorting using the OS.
- m_bUseOsSorting = TRUE;
- m_sortVersion = DEFAULT_SORT_VERSION;
- }
- }
-
-#if _DEBUG
- m_bSortingInitialized = TRUE;
-#endif
-}
-#endif
-
-#ifndef FEATURE_CORECLR
-void AppDomain::InitializeHashing(OBJECTREF* ppAppdomainSetup)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- THROWS;
- GC_NOTRIGGER;
- PRECONDITION(ppAppdomainSetup == NULL || IsProtectedByGCFrame(ppAppdomainSetup));
- }
- CONTRACTL_END;
-
- m_pNlsHashProvider = new COMNlsHashProvider;
-#ifdef FEATURE_RANDOMIZED_STRING_HASHING
- BOOL fUseRandomizedHashing = (BOOL) CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_UseRandomizedStringHashAlgorithm);
-
- if(ppAppdomainSetup != NULL)
- {
- APPDOMAINSETUPREF adSetup = (APPDOMAINSETUPREF) *ppAppdomainSetup;
- fUseRandomizedHashing |= adSetup->UseRandomizedStringHashing();
- }
-
- m_pNlsHashProvider->SetUseRandomHashing(fUseRandomizedHashing);
-#endif // FEATURE_RANDOMIZED_STRING_HASHING
-}
-#endif // FEATURE_CORECLR
OBJECTREF AppDomain::DoSetup(OBJECTREF* setupInfo)
{
return false;
}
-#ifdef FEATURE_CORECLR
return StrongNameIsSilverlightPlatformKey(pbPublicKey, cbPublicKey);
-#else
- return StrongNameIsEcmaKey(pbPublicKey, cbPublicKey);
-#endif
}
void AppDomain::AddAssembly(DomainAssembly * assem)
RETURN ((APPDOMAINREF)GetExposedObject())->HasSetPolicy();
}
-#if defined (FEATURE_LOADER_OPTIMIZATION) && !defined(FEATURE_CORECLR)
-// Returns true if the user has declared the desire to load an
-// assembly domain-neutral. This is either by specifying System.LoaderOptimizationAttribute
-// on the entry routine or the host has set this loader-optimization flag.
-BOOL AppDomain::ApplySharePolicy(DomainAssembly *pFile)
-{
- CONTRACT(BOOL)
- {
- PRECONDITION(CheckPointer(pFile));
- THROWS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- if (!pFile->GetFile()->IsShareable())
- RETURN FALSE;
-
- if (ApplySharePolicyFlag(pFile))
- RETURN TRUE;
-
- RETURN FALSE;
-}
-
-BOOL AppDomain::ApplySharePolicyFlag(DomainAssembly *pFile)
-{
- CONTRACT(BOOL)
- {
- PRECONDITION(CheckPointer(pFile));
- THROWS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- switch(GetSharePolicy()) {
- case SHARE_POLICY_ALWAYS:
- RETURN (!pFile->MayHaveUnknownDependencies());
-
- case SHARE_POLICY_GAC:
- RETURN (pFile->IsClosedInGAC());
-
- case SHARE_POLICY_NEVER:
- RETURN pFile->IsSystem();
-
- default:
- UNREACHABLE_MSG("Unknown share policy");
- }
-}
-#endif // FEATURE_LOADER_OPTIMIZATION
EEClassFactoryInfoHashTable* AppDomain::SetupClassFactHash()
{
Exception* pEx=GET_EXCEPTION();
if (!pEx->IsTransient())
{
-#if defined(FEATURE_CORECLR)
// Setup the binder reference in AssemblySpec from the PEAssembly if one is not already set.
ICLRPrivBinder* pCurrentBindingContext = pSpec->GetBindingContext();
ICLRPrivBinder* pBindingContextFromPEAssembly = pFile->GetBindingContext();
_ASSERTE(AreSameBinderInstance(pCurrentBindingContext, pBindingContextFromPEAssembly));
}
#endif // _DEBUG
-#endif // defined(FEATURE_CORECLR)
if (!EEFileLoadException::CheckType(pEx))
{
EX_TRY
{
-#ifndef FEATURE_CORECLR
- // Event Tracing for Windows is used to log data for performance and functional testing purposes.
- // The events below are used to measure the performance of two steps in the assembly loader, namely assembly initialization and delivering events.
- StackSString ETWAssemblySimpleName;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD))
- {
- LPCUTF8 simpleName = pFile->GetSimpleName();
- ETWAssemblySimpleName.AppendUTF8(simpleName ? simpleName : "NULL"); // Gather data used by ETW events later in this function.
- }
-#endif // FEATURE_CORECLR
// Special case: for LoadLibrary, we cannot hold the lock during the
// actual LoadLibrary call, because we might get a callback from _CorDllMain on any
lockHolder.Release();
released = TRUE;
}
-#ifndef FEATURE_CORECLR
- else if (workLevel == FILE_LOAD_DELIVER_EVENTS)
- {
- FireEtwLoaderDeliverEventsPhaseStart(GetId().m_dwId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, NULL, ETWAssemblySimpleName, GetClrInstanceId());
- }
-#endif // FEATURE_CORECLR
// Do the work
TESTHOOKCALL(NextFileLoadLevel(GetId().m_dwId,pFile,workLevel));
-#ifndef FEATURE_CORECLR
- if (workLevel == FILE_LOAD_ALLOCATE)
- {
- FireEtwLoaderAssemblyInitPhaseStart(GetId().m_dwId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, NULL, ETWAssemblySimpleName, GetClrInstanceId());
- }
-#endif // FEATURE_CORECLR
BOOL success = pFile->DoIncrementalLoad(workLevel);
-#ifndef FEATURE_CORECLR
- if (workLevel == FILE_LOAD_ALLOCATE)
- {
- FireEtwLoaderAssemblyInitPhaseEnd(GetId().m_dwId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, NULL, ETWAssemblySimpleName, GetClrInstanceId());
- }
-#endif // FEATURE_CORECLR
TESTHOOKCALL(CompletingFileLoadLevel(GetId().m_dwId,pFile,workLevel));
if (released)
{
lockHolder.Release();
released = TRUE;
pFile->DeliverAsyncEvents();
-#ifndef FEATURE_CORECLR
- FireEtwLoaderDeliverEventsPhaseEnd(GetId().m_dwId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, NULL, ETWAssemblySimpleName, GetClrInstanceId());
-#endif // FEATURE_CORECLR
};
}
}
#endif // FEATURE_LOADER_OPTIMIZATION
-#ifdef FEATURE_CORECLR
void AppDomain::CheckForMismatchedNativeImages(AssemblySpec * pSpec, const GUID * pGuid)
{
STANDARD_VM_CONTRACT;
amTracker.SuppressRelease();
}
}
-#endif // FEATURE_CORECLR
void AppDomain::SetupSharedStatics()
return m_AssemblyCache.Contains(pSpec);
}
-#ifdef FEATURE_CORECLR
void AppDomain::GetCacheAssemblyList(SetSHash<PTR_DomainAssembly>& assemblyList)
{
CrstHolder holder(&m_DomainCacheCrst);
m_AssemblyCache.GetAllAssemblies(assemblyList);
}
-#endif
PEAssembly* AppDomain::FindCachedFile(AssemblySpec* pSpec, BOOL fThrow /*=TRUE*/)
{
}
fAddFileToCache = true;
-#if defined(FEATURE_CORECLR)
// Setup the reference to the binder, which performed the bind, into the AssemblySpec
ICLRPrivBinder* pBinder = result->GetBindingContext();
_ASSERTE(pBinder != NULL);
pSpec->SetBindingContext(pBinder);
-#endif // defined(FEATURE_CORECLR)
}
#endif //!FEATURE_FUSION
orSender = pAppDomain->GetRawExposedObject();
retVal = pAppDomain->RaiseUnhandledExceptionEventNoThrow(&orSender, pThrowable, isTerminating);
-#ifndef FEATURE_CORECLR
-// CoreCLR#520:
-// To make this work correctly we need the changes for coreclr 473
- if (pAppDomain != SystemDomain::System()->DefaultDomain())
- retVal |= SystemDomain::System()->DefaultDomain()->RaiseUnhandledExceptionEventNoThrow
- (&orSender, pThrowable, isTerminating);
-#endif
GCPROTECT_END();
}
}
-#ifndef FEATURE_CORECLR
-void AppDomain::RaiseUnhandledExceptionEvent_Wrapper(LPVOID ptr)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- SO_INTOLERANT;
- }
- CONTRACTL_END;
- AppDomain::RaiseUnhandled_Args *args = (AppDomain::RaiseUnhandled_Args *) ptr;
-
- struct _gc {
- OBJECTREF orThrowable;
- OBJECTREF orSender;
- } gc;
-
- ZeroMemory(&gc, sizeof(gc));
-
- _ASSERTE(args->pTargetDomain == GetAppDomain());
- GCPROTECT_BEGIN(gc);
- EX_TRY
- {
- SetObjectReference(&gc.orThrowable,
- AppDomainHelper::CrossContextCopyFrom(args->pExceptionDomain,
- args->pThrowable),
- args->pTargetDomain);
-
- SetObjectReference(&gc.orSender,
- AppDomainHelper::CrossContextCopyFrom(args->pExceptionDomain,
- args->pSender),
- args->pTargetDomain);
- }
- EX_CATCH
- {
- SetObjectReference(&gc.orThrowable, GET_THROWABLE(), args->pTargetDomain);
- SetObjectReference(&gc.orSender, GetAppDomain()->GetRawExposedObject(), args->pTargetDomain);
- }
- EX_END_CATCH(SwallowAllExceptions)
- *(args->pResult) = args->pTargetDomain->RaiseUnhandledExceptionEvent(&gc.orSender,
- &gc.orThrowable,
- args->isTerminating);
- GCPROTECT_END();
-
-}
-#endif //!FEATURE_CORECLR
BOOL
AppDomain::RaiseUnhandledExceptionEventNoThrow(OBJECTREF *pSender, OBJECTREF *pThrowable, BOOL isTerminating)
_ASSERTE(pThrowable != NULL && IsProtectedByGCFrame(pThrowable));
_ASSERTE(pSender != NULL && IsProtectedByGCFrame(pSender));
-#ifndef FEATURE_CORECLR
- Thread *pThread = GetThread();
- if (this != pThread->GetDomain())
- {
- RaiseUnhandled_Args args = {pThread->GetDomain(), this, pSender, pThrowable, isTerminating, &result};
- // call through DoCallBack with a domain transition
- pThread->DoADCallBack(this, AppDomain::RaiseUnhandledExceptionEvent_Wrapper, &args, ADV_DEFAULTAD);
- return result;
- }
-#else
_ASSERTE(this == GetThread()->GetDomain());
-#endif
OBJECTREF orDelegate = NULL;
}
-#ifndef FEATURE_CORECLR
-// Create a domain based on a string name
-AppDomain* AppDomain::CreateDomainContext(LPCWSTR fileName)
-{
- CONTRACTL
- {
- THROWS;
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- if(fileName == NULL) return NULL;
-
- AppDomain* pDomain = NULL;
-
- MethodDescCallSite valCreateDomain(METHOD__APP_DOMAIN__VAL_CREATE_DOMAIN);
-
- STRINGREF pFilePath = NULL;
- GCPROTECT_BEGIN(pFilePath);
- pFilePath = StringObject::NewString(fileName);
-
- ARG_SLOT args[1] =
- {
- ObjToArgSlot(pFilePath),
- };
-
- APPDOMAINREF pDom = (APPDOMAINREF) valCreateDomain.Call_RetOBJECTREF(args);
- if(pDom != NULL)
- {
- Context* pContext = Context::GetExecutionContext(pDom);
- if(pContext)
- {
- pDomain = pContext->GetDomain();
- }
- }
- GCPROTECT_END();
-
- return pDomain;
-}
-#endif // !FEATURE_CORECLR
#endif // CROSSGEN_COMPILE
gc.pConfig = StringObject::NewString(pwszConfig);
}
-#ifndef FEATURE_CORECLR
- StringArrayList *pPropertyNames;
- StringArrayList *pPropertyValues;
- CorHost2::GetDefaultAppDomainProperties(&pPropertyNames, &pPropertyValues);
-
- _ASSERTE(pPropertyNames->GetCount() == pPropertyValues->GetCount());
-
- if (pPropertyNames->GetCount() > 0)
- {
- gc.propertyNames = (PTRARRAYREF)AllocateObjectArray(pPropertyNames->GetCount(), g_pStringClass);
- gc.propertyValues = (PTRARRAYREF)AllocateObjectArray(pPropertyValues->GetCount(), g_pStringClass);
-
- for (DWORD i = 0; i < pPropertyNames->GetCount(); ++i)
- {
- STRINGREF propertyName = StringObject::NewString(pPropertyNames->Get(i));
- gc.propertyNames->SetAt(i, propertyName);
-
- STRINGREF propertyValue = StringObject::NewString(pPropertyValues->Get(i));
- gc.propertyValues->SetAt(i, propertyValue);
- }
- }
-#endif // !FEATURE_CORECLR
if ((gc.ref = GetExposedObject()) != NULL)
{
IfFailThrow(FusionBind::CreateFusionContext(NULL, &pFusionContext));
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
- CLRPrivBinderWinRT * pWinRtBinder;
- if (AppX::IsAppXProcess())
- { // Note: Fusion binder is used in AppX to bind .NET Fx assemblies - some of them depend on .winmd files (e.g. System.Runtime.WindowsRuntime.dll)
- CLRPrivBinderAppX * pAppXBinder = CLRPrivBinderAppX::GetOrCreateBinder();
- pWinRtBinder = pAppXBinder->GetWinRtBinder();
- }
- else
- {
- pWinRtBinder = m_pWinRtBinder;
- }
- _ASSERTE(pWinRtBinder != nullptr);
-
- IfFailThrow(SetApplicationContext_WinRTBinder(
- pFusionContext,
- static_cast<IBindContext *>(pWinRtBinder)));
-#endif
#ifdef FEATURE_PREJIT
if (NGENImagesAllowed())
{
if (pSpec->GetParentAssembly() != NULL)
{
-#ifndef FEATURE_CORECLR
- if ( pSpec->IsIntrospectionOnly()
-#ifdef FEATURE_FUSION
- || pSpec->GetParentLoadContext() == LOADCTX_TYPE_UNKNOWN
-#endif
- )
-#endif // FEATURE_CORECLR
{
gc.AssemblyRef=pSpec->GetParentAssembly()->GetExposedAssemblyObject();
}
RETURN pAssembly;
} // AppDomain::RaiseAssemblyResolveEvent
-#ifndef FEATURE_CORECLR
-
-//---------------------------------------------------------------------------------------
-//
-// Ask the AppDomainManager for the entry assembly of the application
-//
-// Note:
-// Most AppDomainManagers will fall back on the root assembly for the domain, so we need
-// to make sure this is set before we call through to the AppDomainManager itself.
-//
-
-Assembly *AppDomain::GetAppDomainManagerEntryAssembly()
-{
- CONTRACT(Assembly *)
- {
- STANDARD_VM_CHECK;
- PRECONDITION(HasAppDomainManagerInfo());
- PRECONDITION(CheckPointer(m_pRootAssembly));
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- GCX_COOP();
-
- Assembly *pEntryAssembly = NULL;
-
- struct
- {
- APPDOMAINREF orDomain;
- OBJECTREF orAppDomainManager;
- ASSEMBLYREF orEntryAssembly;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.orDomain = static_cast<APPDOMAINREF>(GetExposedObject());
- gc.orAppDomainManager = gc.orDomain->GetAppDomainManager();
- _ASSERTE(gc.orAppDomainManager != NULL);
-
- MethodDescCallSite getEntryAssembly(METHOD__APPDOMAIN_MANAGER__GET_ENTRY_ASSEMBLY, &gc.orAppDomainManager);
- ARG_SLOT argThis = ObjToArgSlot(gc.orAppDomainManager);
- gc.orEntryAssembly = static_cast<ASSEMBLYREF>(getEntryAssembly.Call_RetOBJECTREF(&argThis));
-
- if (gc.orEntryAssembly != NULL)
- {
- pEntryAssembly = gc.orEntryAssembly->GetAssembly();
- }
-
- GCPROTECT_END();
-
- // If the AppDomainManager did not return an entry assembly, we'll assume the default assembly
- if (pEntryAssembly == NULL)
- {
- pEntryAssembly = m_pRootAssembly;
- }
-
- RETURN(pEntryAssembly);
-}
-
-#endif // !FEATURE_CORECLR
//---------------------------------------------------------------------------------------
//
LOG((LF_APPDOMAIN, LL_INFO10, "Setting default AppDomainManager '%S', '%S' from hosting API.\n", GetAppDomainManagerAsm(), GetAppDomainManagerType()));
}
-#ifndef FEATURE_CORECLR
- else
- {
- CLRConfigStringHolder wszConfigAppDomainManagerAssembly(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_AppDomainManagerAsm));
- CLRConfigStringHolder wszConfigAppDomainManagerType(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_AppDomainManagerType));
-
- if (wszConfigAppDomainManagerAssembly != NULL &&
- wszConfigAppDomainManagerType != NULL)
- {
- SetAppDomainManagerInfo(wszConfigAppDomainManagerAssembly,
- wszConfigAppDomainManagerType,
- eInitializeNewDomainFlags_None);
- m_fAppDomainManagerSetInConfig = TRUE;
-
- LOG((LF_APPDOMAIN, LL_INFO10, "Setting default AppDomainManager '%S', '%S' from application config file.\n", GetAppDomainManagerAsm(), GetAppDomainManagerType()));
- }
- else
- {
- CLRConfigStringHolder wszEnvironmentAppDomainManagerAssembly(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_LEGACY_APPDOMAIN_MANAGER_ASM));
- CLRConfigStringHolder wszEnvironmentAppDomainManagerType(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_LEGACY_APPDOMAIN_MANAGER_TYPE));
-
- if (wszEnvironmentAppDomainManagerAssembly != NULL &&
- wszEnvironmentAppDomainManagerType != NULL)
- {
- SetAppDomainManagerInfo(wszEnvironmentAppDomainManagerAssembly,
- wszEnvironmentAppDomainManagerType,
- eInitializeNewDomainFlags_None);
- m_fAppDomainManagerSetInConfig = FALSE;
-
- LOG((LF_APPDOMAIN, LL_INFO10, "Setting default AppDomainManager '%S', '%S' from environment variables.\n", GetAppDomainManagerAsm(), GetAppDomainManagerType()));
-
- // Reset the environmetn variables so that child processes do not inherit our domain manager
- // by default.
- WszSetEnvironmentVariable(CLRConfig::EXTERNAL_LEGACY_APPDOMAIN_MANAGER_ASM.name, NULL);
- WszSetEnvironmentVariable(CLRConfig::EXTERNAL_LEGACY_APPDOMAIN_MANAGER_TYPE.name, NULL);
- }
- }
- }
-#endif // !FEATURE_CORECLR
// If we found an AppDomain manager to use, create and initialize it
// Otherwise, initialize the config flags.
{
STANDARD_VM_CONTRACT;
-#ifdef FEATURE_CORECLR
// Do not create adUnload thread if there is only default domain
if(IsSingleAppDomain())
return;
-#endif
Retry:
BOOL fCreator = FALSE;
#ifndef DACCESS_COMPILE
-#ifndef FEATURE_CORECLR
-//------------------------------------------------------------------------
-DWORD* SetupCompatibilityFlags()
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- } CONTRACTL_END;
-
- LPCWSTR buf;
- bool return_null = true;
-
- FAULT_NOT_FATAL(); // we can simply give up
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return NULL;)
- InlineSString<4> bufString;
-
- if (WszGetEnvironmentVariable(W("UnsupportedCompatSwitchesEnabled"), bufString) != 0)
- {
- buf = bufString.GetUnicode();
- if (buf[0] != '1' || buf[1] != '\0')
- {
- return_null = true;
- }
- else
- {
- return_null = false;
- }
-
- }
- END_SO_INTOLERANT_CODE
-
- if (return_null)
- return NULL;
-
- static const LPCWSTR rgFlagNames[] = {
-#define COMPATFLAGDEF(name) TEXT(#name),
-#include "compatibilityflagsdef.h"
- };
-
- int size = (compatCount+31) / 32;
- DWORD* pFlags = new (nothrow) DWORD[size];
- if (pFlags == NULL)
- return NULL;
- ZeroMemory(pFlags, size * sizeof(DWORD));
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return NULL;)
- InlineSString<4> bufEnvString;
- for (int i = 0; i < COUNTOF(rgFlagNames); i++)
- {
- if (WszGetEnvironmentVariable(rgFlagNames[i], bufEnvString) == 0)
- continue;
-
- buf = bufEnvString.GetUnicode();
- if (buf[0] != '1' || buf[1] != '\0')
- continue;
-
- pFlags[i / 32] |= 1 << (i % 32);
- }
- END_SO_INTOLERANT_CODE
-
- return pFlags;
-}
-
-//------------------------------------------------------------------------
-static VolatilePtr<DWORD> g_pCompatibilityFlags = (DWORD*)(-1);
-
-DWORD* GetGlobalCompatibilityFlags()
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- } CONTRACTL_END;
-
- if (g_pCompatibilityFlags == (DWORD*)(-1))
- {
- DWORD *pCompatibilityFlags = SetupCompatibilityFlags();
-
- if (FastInterlockCompareExchangePointer(g_pCompatibilityFlags.GetPointer(), pCompatibilityFlags, reinterpret_cast<DWORD *>(-1)) != (VOID*)(-1))
- {
- delete [] pCompatibilityFlags;
- }
- }
-
- return g_pCompatibilityFlags;
-}
-#endif // !FEATURE_CORECLR
//------------------------------------------------------------------------
BOOL GetCompatibilityFlag(CompatibilityFlag flag)
SO_TOLERANT;
} CONTRACTL_END;
-#ifndef FEATURE_CORECLR
- DWORD *pFlags = GetGlobalCompatibilityFlags();
-
- if (pFlags != NULL)
- return (pFlags[flag / 32] & (1 << (flag % 32))) ? TRUE : FALSE;
- else
- return FALSE;
-#else // !FEATURE_CORECLR
return FALSE;
-#endif // !FEATURE_CORECLR
}
#endif // !DACCESS_COMPILE
return FALSE;
} // AppDomain::AssemblyIterator::Next_UnsafeNoAddRef
-#ifdef FEATURE_CORECLR
//---------------------------------------------------------------------------------------
//
return IsImageFromTrustedPath(pPEImage);
}
-#endif //FEATURE_CORECLR
#endif //!DACCESS_COMPILE
}
}
-#if defined(FEATURE_CORECLR) && defined(FEATURE_COMINTEROP)
+#if defined(FEATURE_COMINTEROP)
HRESULT AppDomain::SetWinrtApplicationContext(SString &appLocalWinMD)
{
STANDARD_VM_CONTRACT;
}
}
-#if !defined(DACCESS_COMPILE) && defined(FEATURE_CORECLR) && defined(FEATURE_NATIVE_IMAGE_GENERATION)
+#if !defined(DACCESS_COMPILE) && defined(FEATURE_NATIVE_IMAGE_GENERATION)
void ZapperSetBindingPaths(ICorCompilationDomain *pDomain, SString &trustedPlatformAssemblies, SString &platformResourceRoots, SString &appPaths, SString &appNiPaths)
{
#endif
-#if defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
+#if !defined(CROSSGEN_COMPILE)
bool IsSingleAppDomain()
{
STARTUP_FLAGS flags = CorHost2::GetStartupFlags();
#ifdef FEATURE_COMINTEROP
#include "clrprivbinderwinrt.h"
-#ifndef FEATURE_CORECLR
-#include "clrprivbinderreflectiononlywinrt.h"
-#include "clrprivtypecachereflectiononlywinrt.h"
-#endif
#include "..\md\winmd\inc\adapter.h"
#include "winrttypenameconverter.h"
#endif // FEATURE_COMINTEROP
inline LPCWSTR GetAppDomainManagerType();
inline EInitializeNewDomainFlags GetAppDomainManagerInitializeNewDomainFlags();
-#ifndef FEATURE_CORECLR
- inline BOOL AppDomainManagerSetFromConfig();
- Assembly *GetAppDomainManagerEntryAssembly();
- void ComputeTargetFrameworkName();
-#endif // FEATURE_CORECLR
-#if defined(FEATURE_CORECLR) && defined(FEATURE_COMINTEROP)
+#if defined(FEATURE_COMINTEROP)
HRESULT SetWinrtApplicationContext(SString &appLocalWinMD);
#endif // FEATURE_CORECLR && FEATURE_COMINTEROP
virtual BOOL IsAppDomain() { LIMITED_METHOD_DAC_CONTRACT; return TRUE; }
virtual PTR_AppDomain AsAppDomain() { LIMITED_METHOD_CONTRACT; return dac_cast<PTR_AppDomain>(this); }
-#ifndef FEATURE_CORECLR
- void InitializeSorting(OBJECTREF* ppAppdomainSetup);
- void InitializeHashing(OBJECTREF* ppAppdomainSetup);
-#endif
OBJECTREF DoSetup(OBJECTREF* setupInfo);
return AssemblyIterator::Create(this, assemblyIterationFlags);
}
-#ifdef FEATURE_CORECLR
private:
struct NativeImageDependenciesEntry
{
void SetNativeDllSearchDirectories(LPCWSTR paths);
BOOL HasNativeDllSearchDirectories();
void ShutdownNativeDllSearchDirectories();
-#endif // FEATURE_CORECLR
public:
SIZE_T GetAssemblyCount()
//****************************************************************************************
// Determines if the image is to be loaded into the shared assembly or an individual
// appdomains.
-#ifndef FEATURE_CORECLR
- BOOL ApplySharePolicy(DomainAssembly *pFile);
- BOOL ApplySharePolicyFlag(DomainAssembly *pFile);
-#endif
#endif // FEATURE_LOADER_OPTIMIZATION
BOOL HasSetSecurityPolicy();
BOOL isTerminating;
BOOL *pResult;
};
- #ifndef FEATURE_CORECLR
- static void RaiseUnhandledExceptionEvent_Wrapper(LPVOID /* RaiseUnhandled_Args * */);
- #endif
static void AllowThreadEntrance(AppDomain *pApp);
ILLEGAL_VERIFICATION_DOMAIN = 0x8000, // This can't be a verification domain
IGNORE_UNHANDLED_EXCEPTIONS = 0x10000, // AppDomain was created using the APPDOMAIN_IGNORE_UNHANDLED_EXCEPTIONS flag
ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP = 0x20000, // AppDomain was created using the APPDOMAIN_ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP flag
-#ifdef FEATURE_CORECLR
ENABLE_SKIP_PLAT_CHECKS = 0x200000, // Skip various assembly checks (like platform check)
ENABLE_ASSEMBLY_LOADFILE = 0x400000, // Allow Assembly.LoadFile in CoreCLR
DISABLE_TRANSPARENCY_ENFORCEMENT= 0x800000, // Disable enforcement of security transparency rules
-#endif
};
SecurityContext *m_pSecContext;
BOOL m_fAppDomainManagerSetInConfig;
EInitializeNewDomainFlags m_dwAppDomainManagerInitializeDomainFlags;
-#ifdef FEATURE_CORECLR
ArrayList m_NativeDllSearchDirectories;
-#endif
BOOL m_ReversePInvokeCanEnter;
bool m_ForceTrivialWaitOperations;
// Section to support AD unload due to escalation
return (m_Stage == STAGE_UNLOAD_REQUESTED);
}
-#ifdef FEATURE_CORECLR
BOOL IsImageFromTrustedPath(PEImage* pImage);
BOOL IsImageFullyTrusted(PEImage* pImage);
-#endif
#ifdef FEATURE_TYPEEQUIVALENCE
private:
#endif //FEATURE_COMINTEROP
public:
-#ifndef FEATURE_CORECLR
- BOOL m_bUseOsSorting;
- DWORD m_sortVersion;
- COMNlsCustomSortLibrary *m_pCustomSortLibrary;
-#if _DEBUG
- BOOL m_bSortingInitialized;
-#endif // _DEBUG
- COMNlsHashProvider *m_pNlsHashProvider;
-#endif // !FEATURE_CORECLR
private:
// This is the root-level default load context root binder. If null, then
}
#endif // DACCESS_COMPILE
-#ifndef FEATURE_CORECLR
- static void ExecuteMainMethod(HMODULE hMod, __in_opt LPWSTR path = NULL);
-#endif
static void ActivateApplication(int *pReturnValue);
static void InitializeDefaultDomain(BOOL allowRedirects, ICLRPrivBinder * pBinder = NULL);
return m_AppDomainManagerType;
}
-#ifndef FEATURE_CORECLR
-inline BOOL AppDomain::AppDomainManagerSetFromConfig()
-{
- WRAPPER_NO_CONTRACT;
- return m_fAppDomainManagerSetInConfig;
-}
-#endif // !FEATURE_CORECLR
inline EInitializeNewDomainFlags AppDomain::GetAppDomainManagerInitializeNewDomainFlags()
{
return m_dwAppDomainManagerInitializeDomainFlags;
}
-#ifdef FEATURE_CORECLR
inline AppDomain::PathIterator AppDomain::IterateNativeDllSearchDirectories()
{
WRAPPER_NO_CONTRACT;
return m_NativeDllSearchDirectories.GetCount() !=0;
}
-#endif // FEATURE_CORECLR
inline BOOL AppDomain::CanReversePInvokeEnter()
{
#include "eeconfig.h"
#include "appdomain.inl"
#include "eventtrace.h"
-#ifndef FEATURE_CORECLR
-#include "comutilnative.h"
-#endif // !FEATURE_CORECLR
#if defined(FEATURE_APPX)
#include "appxutil.h"
#endif // FEATURE_APPX
setupInfo = prepareDataForSetup.Call_RetOBJECTREF(args);
-#ifndef FEATURE_CORECLR
- // We need to setup domain sorting before any other managed code runs in the domain, since that code
- // could end up caching data based on the sorting mode of the domain.
- pDomain->InitializeSorting(ppAppdomainSetup);
- pDomain->InitializeHashing(ppAppdomainSetup);
-#endif
// We need to ensure that the AppDomainProxy is generated before we call into DoSetup, since
// GetAppDomainProxy will ensure that remoting is correctly configured in the domain. DoSetup can
}
}
-#ifdef FEATURE_CAS_POLICY
- if (gc.orEvidence != NULL)
- {
- pSecDesc->SetEvidence(gc.orEvidence);
- }
-#endif // FEATURE_CAS_POLICY
// We need to downgrade sharing level if the AppDomain is homogeneous and not fully trusted, or the
// AppDomain is in legacy mode. Effectively, we need to be sure that all assemblies loaded into the
END_QCALL;
}
-#ifdef FEATURE_CAS_POLICY
-
-// static
-void QCALLTYPE AppDomainNative::SetLegacyCasPolicyEnabled(QCall::AppDomainHandle adhTarget)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- IApplicationSecurityDescriptor *pAppSecDesc = adhTarget->GetSecurityDescriptor();
- pAppSecDesc->SetLegacyCasPolicyEnabled();
-
- END_QCALL;
-}
-
-// static
-BOOL QCALLTYPE AppDomainNative::IsLegacyCasPolicyEnabled(QCall::AppDomainHandle adhTarget)
-{
- QCALL_CONTRACT;
-
- BOOL fLegacyCasPolicy = FALSE;
-
- BEGIN_QCALL;
-
- IApplicationSecurityDescriptor *pAppSecDesc = adhTarget->GetSecurityDescriptor();
- fLegacyCasPolicy = !!pAppSecDesc->IsLegacyCasPolicyEnabled();
-
- END_QCALL;
-
- return fLegacyCasPolicy;
-}
-
-#endif // FEATURE_CAS_POLICY
-
-#ifdef FEATURE_APTCA
-
-// static
-void QCALLTYPE AppDomainNative::SetCanonicalConditionalAptcaList(QCall::AppDomainHandle adhTarget,
- LPCWSTR wszCanonicalConditionalAptcaList)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- IApplicationSecurityDescriptor *pAppSecDesc = adhTarget->GetSecurityDescriptor();
-
- GCX_COOP();
- pAppSecDesc->SetCanonicalConditionalAptcaList(wszCanonicalConditionalAptcaList);
-
- END_QCALL;
-}
-#endif // FEATURE_APTCA
FCIMPL1(Object*, AppDomainNative::GetFriendlyName, AppDomainBaseObject* refThisUNSAFE)
{
}
FCIMPLEND
-#ifdef FEATURE_CORECLR
void QCALLTYPE AppDomainNative::SetNativeDllSearchDirectories(__in_z LPCWSTR wszNativeDllSearchDirectories)
{
END_QCALL;
}
-#endif // FEATURE_CORECLR
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
FCIMPL0(void, AppDomainNative::EnableMonitoring)
static FCDECL2(FC_BOOL_RET, IsFrameworkAssembly, AppDomainBaseObject* refThisUNSAFE, AssemblyNameBaseObject* refAssemblyNameUNSAFE);
static FCDECL1(UINT32, GetAppDomainId, AppDomainBaseObject* refThisUNSAFE);
static FCDECL1(void , PublishAnonymouslyHostedDynamicMethodsAssembly, AssemblyBaseObject * pAssemblyUNSAFE);
-#ifdef FEATURE_CORECLR
static void QCALLTYPE SetNativeDllSearchDirectories(__in_z LPCWSTR wszAssembly);
-#endif // FEATURE_CORECLR
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
static FCDECL0(void, EnableMonitoring);
void QCALLTYPE SetSecurityHomogeneousFlag(QCall::AppDomainHandle adhTarget,
BOOL fRuntimeSuppliedHomgenousGrantSet);
-#ifdef FEATURE_CAS_POLICY
- static
- void QCALLTYPE SetLegacyCasPolicyEnabled(QCall::AppDomainHandle adhTarget);
-
- static
- BOOL QCALLTYPE IsLegacyCasPolicyEnabled(QCall::AppDomainHandle adhTarget);
-#endif // FEATURE_CAS_POLICY
-#ifdef FEATURE_APTCA
- static
- void QCALLTYPE SetCanonicalConditionalAptcaList(QCall::AppDomainHandle adhTarget,
- LPCWSTR wszCanonicalConditionalAptcaList);
-#endif // FEATURE_APTCA
#ifdef FEATURE_APPDOMAINMANAGER_INITOPTIONS
static
}
CONTRACTL_END
-#ifdef FEATURE_CORECLR
// CoreCLR does not have proper support for AppX design mode. Once/if it has one, it should not need
// any special casing like desktop. Avoid the expensive check completely.
return false;
-#else
- // DevMode does not change over the lifetime of a process and is expensive to compute
- // Cache the first answer and return it once computed; idempotent so races are fine
- static enum
- {
- CachedAppxMode_Unknown,
- CachedAppxMode_Normal,
- CachedAppxMode_Design
- }
- s_cachedAppxMode = CachedAppxMode_Unknown;
-
- bool result = false;
-
- switch (s_cachedAppxMode)
- {
- case CachedAppxMode_Unknown:
- if (SUCCEEDED(IsAppXDesignModeWorker(&result)))
- { // Cache the result on success; otherwise use the default value of false.
- s_cachedAppxMode = result ? CachedAppxMode_Design : CachedAppxMode_Normal;
- }
- break;
-
- case CachedAppxMode_Normal:
- result = false;
- break;
-
- case CachedAppxMode_Design:
- result = true;
- break;
- }
-
-#ifdef _DEBUG
- bool dbg_result = false;
- _ASSERTE(FAILED(IsAppXDesignModeWorker(&dbg_result)) || dbg_result == result);
-#endif
-
- return result;
-#endif // FEATURE_CORECLR
}
HRESULT GetApplicationId(LPCWSTR& rString)
+++ /dev/null
-// 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.
-//--------------------------------------------------------------------------
-// aptca.h
-//
-// Functions for handling allow partially trusted callers assemblies
-//
-
-//
-//--------------------------------------------------------------------------
-
-
-#include "common.h"
-#include "aptca.h"
-
-//
-// Conditional APTCA cache implementation
-//
-
-ConditionalAptcaCache::ConditionalAptcaCache(AppDomain *pAppDomain)
- : m_pAppDomain(pAppDomain),
- m_canonicalListIsNull(false),
- m_domainState(kDomainStateUnknown)
-{
- WRAPPER_NO_CONTRACT;
-
- _ASSERTE(pAppDomain != NULL);
-}
-
-ConditionalAptcaCache::~ConditionalAptcaCache()
-{
- WRAPPER_NO_CONTRACT;
-}
-
-void ConditionalAptcaCache::SetCachedState(PTR_PEImage pImage, ConditionalAptcaCache::State state)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pImage));
- PRECONDITION(state != kUnknown);
- }
- CONTRACTL_END;
-
- if (state == kNotCAptca)
- {
- pImage->SetIsNotConditionalAptca();
- }
-}
-
-ConditionalAptcaCache::State ConditionalAptcaCache::GetCachedState(PTR_PEImage pImage)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pImage));
- }
- CONTRACTL_END;
-
- if (!pImage->MayBeConditionalAptca())
- {
- return kNotCAptca;
- }
-
- return kUnknown;
-}
-
-void ConditionalAptcaCache::SetCanonicalConditionalAptcaList(LPCWSTR wszCanonicalConditionalAptcaList)
-{
- WRAPPER_NO_CONTRACT;
- m_canonicalListIsNull = (wszCanonicalConditionalAptcaList == NULL);
- m_canonicalList.Set(wszCanonicalConditionalAptcaList);
-}
-
-#ifndef CROSSGEN_COMPILE
-ConditionalAptcaCache::DomainState ConditionalAptcaCache::GetConditionalAptcaDomainState()
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- THROWS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (m_domainState == kDomainStateUnknown)
- {
- IApplicationSecurityDescriptor *pASD = m_pAppDomain->GetSecurityDescriptor();
- DomainState domainState = kDomainStateUnknown;
-
- // In the full trust case we only need to look at the conditional APTCA list in the case that the host
- // has configured one on the default domain (for instance WPF). Otherwise, all full trust domains have
- // all conditional APTCA assemblies enabled.
- bool processFullTrustAptcaList = false;
- if (m_pAppDomain->IsCompilationDomain())
- {
- processFullTrustAptcaList = false;
- }
- else if (m_pAppDomain->IsDefaultDomain())
- {
- processFullTrustAptcaList = !m_canonicalListIsNull;
- }
- else
- {
- processFullTrustAptcaList = ConsiderFullTrustConditionalAptcaLists();
- }
-
- // Consider the domain to be fully trusted if it really is fully trusted, or if we're currently
- // setting the domain up, it looks like it will be fully trusted, and the AppDomainManager has
- // promised that won't change.
- bool isFullTrustDomain = !m_pAppDomain->GetSecurityDescriptor()->DomainMayContainPartialTrustCode();
- if (pASD->IsInitializationInProgress() && (m_pAppDomain->GetAppDomainManagerInitializeNewDomainFlags() & eInitializeNewDomainFlags_NoSecurityChanges))
- {
- BOOL preResolveFullTrust;
- BOOL preResolveHomogenous;
- pASD->PreResolve(&preResolveFullTrust, &preResolveHomogenous);
-
- isFullTrustDomain = preResolveFullTrust && preResolveHomogenous;
- }
-
- if (m_pAppDomain->IsCompilationDomain())
- {
- // NGEN always enables all conditional APTCA assemblies
- domainState = kAllEnabled;
- }
- else if (!isFullTrustDomain || processFullTrustAptcaList)
- {
- if (m_canonicalList.GetCount() == 0)
- {
- // A null or empty conditional APTCA list means that no assemblies are enabled in this domain
- domainState = kAllDisabled;
- }
- else
- {
- // We're in a domain that supports conditional APTCA and an interesting list is supplied. In
- // this domain, some assemblies are enabled.
- domainState = kSomeEnabled;
- }
- }
- else
- {
- domainState = kAllEnabled;
- }
-
- _ASSERTE(domainState != kDomainStateUnknown);
- InterlockedCompareExchange(reinterpret_cast<volatile LONG *>(&m_domainState), domainState, kDomainStateUnknown);
- }
-
- return m_domainState;
-}
-
-// static
-bool ConditionalAptcaCache::ConsiderFullTrustConditionalAptcaLists()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (GetAppDomain()->IsCompilationDomain())
- {
- return false;
- }
-
- IApplicationSecurityDescriptor *pASD = SystemDomain::System()->DefaultDomain()->GetSecurityDescriptor();
- ConditionalAptcaCache *pDefaultDomainCaptca = pASD->GetConditionalAptcaCache();
-
- // The only way that we use CAPTCA lists is if the host has configured the default domain to not be all
- // enabled (that is, the host has setup a CAPTCA list of any sort for the default domain)
- return pDefaultDomainCaptca->GetConditionalAptcaDomainState() != kAllEnabled;
-}
-
-// APTCA killbit list helper functions
-namespace
-{
- static const LPCWSTR wszAptcaRootKey = W("SOFTWARE\\Microsoft\\.NETFramework\\Policy\\APTCA");
-
- //--------------------------------------------------------------------------------------------------------
- //
- // The AptcaKillBitList class is responsible for holding the machine wide list of assembly name / file
- // versions which have been disabled for APTCA on the machine.
- //
-
- class AptcaKillBitList
- {
- private:
- ArrayList m_killBitList;
-
- public:
- ~AptcaKillBitList();
-
- bool AreAnyAssembliesKillBitted();
- bool IsAssemblyKillBitted(PEAssembly *pAssembly);
- bool IsAssemblyKillBitted(IAssemblyName *pAssemblyName, ULARGE_INTEGER fileVersion);
-
- static AptcaKillBitList *ReadMachineKillBitList();
-
- private:
- AptcaKillBitList();
- AptcaKillBitList(const AptcaKillBitList &other); // not implemented
-
- private:
- static const LPCWSTR wszKillBitValue;
-
- private:
- static bool FileVersionsAreEqual(ULARGE_INTEGER targetVersion, IAssemblyName *pKillBitAssemblyName);
- };
- const LPCWSTR AptcaKillBitList::wszKillBitValue = W("APTCA_FLAG");
-
- AptcaKillBitList::AptcaKillBitList()
- {
- LIMITED_METHOD_CONTRACT;
- }
-
- AptcaKillBitList::~AptcaKillBitList()
- {
- WRAPPER_NO_CONTRACT;
-
- // Release all of the IAssemblyName objects stored in this list
- for (DWORD i = 0; i < m_killBitList.GetCount(); ++i)
- {
- IAssemblyName *pKillBitAssemblyName = reinterpret_cast<IAssemblyName *>(m_killBitList.Get(i));
- if (pKillBitAssemblyName != NULL)
- {
- pKillBitAssemblyName->Release();
- }
- }
- }
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Determine if any assemblies are on the APTCA killbit list
- //
-
- bool AptcaKillBitList::AreAnyAssembliesKillBitted()
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // We don't consider the killbit for NGEN, as ngened code always assumes that APTCA is enabled.
- if (GetAppDomain()->IsCompilationDomain())
- {
- return false;
- }
-
- return m_killBitList.GetCount() > 0;
- }
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Compare the file versions of an assembly with the verison that is being killbitted to see if they
- // match. For compatibility with v3.5, we assume any failure means that the versions do not match.
- //
-
- // static
- bool AptcaKillBitList::FileVersionsAreEqual(ULARGE_INTEGER targetVersion, IAssemblyName *pKillBitAssemblyName)
- {
- DWORD dwKillBitMajorVersion = 0;
- DWORD dwVersionSize = sizeof(dwKillBitMajorVersion);
- if (FAILED(pKillBitAssemblyName->GetProperty(ASM_NAME_FILE_MAJOR_VERSION, &dwKillBitMajorVersion, &dwVersionSize)) ||
- dwVersionSize == 0)
- {
- return false;
- }
-
- DWORD dwKillBitMinorVersion = 0;
- dwVersionSize = sizeof(dwKillBitMinorVersion);
- if (FAILED(pKillBitAssemblyName->GetProperty(ASM_NAME_FILE_MINOR_VERSION, &dwKillBitMinorVersion, &dwVersionSize)) ||
- dwVersionSize == 0)
- {
- return false;
- }
-
- DWORD dwKillBitBuildVersion = 0;
- dwVersionSize = sizeof(dwKillBitBuildVersion);
- if (FAILED(pKillBitAssemblyName->GetProperty(ASM_NAME_FILE_BUILD_NUMBER, &dwKillBitBuildVersion, &dwVersionSize)) ||
- dwVersionSize == 0)
- {
- return false;
- }
-
- DWORD dwKillBitRevisionVersion = 0;
- dwVersionSize = sizeof(dwKillBitRevisionVersion);
- if (FAILED(pKillBitAssemblyName->GetProperty(ASM_NAME_FILE_REVISION_NUMBER, &dwKillBitRevisionVersion, &dwVersionSize)) ||
- dwVersionSize == 0)
- {
- return false;
- }
-
- DWORD dwTargetMajorVersion = (targetVersion.HighPart & 0xFFFF0000) >> 16;
- DWORD dwTargetMinorVersion = targetVersion.HighPart & 0x0000FFFF;
- DWORD dwTargetBuildVersion = (targetVersion.LowPart & 0xFFFF0000) >> 16;
- DWORD dwTargetRevisionVersion = targetVersion.LowPart & 0x0000FFFF;
-
- return dwTargetMajorVersion == dwKillBitMajorVersion &&
- dwTargetMinorVersion == dwKillBitMinorVersion &&
- dwTargetBuildVersion == dwKillBitBuildVersion &&
- dwTargetRevisionVersion == dwKillBitRevisionVersion;
- }
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Determine if a specific assembly is on the killbit list
- //
-
- bool AptcaKillBitList::IsAssemblyKillBitted(PEAssembly *pAssembly)
- {
- STANDARD_VM_CONTRACT;
-
- IAssemblyName *pTargetAssemblyName = pAssembly->GetFusionAssemblyName();
-
- // For compat with v3.5, we use hte Win32 file version here rather than the Fusion version
- LPCWSTR pwszPath = pAssembly->GetPath().GetUnicode();
- if (pwszPath != NULL)
- {
- ULARGE_INTEGER fileVersion = { 0, 0 };
- HRESULT hr = GetFileVersion(pwszPath, &fileVersion);
- if (SUCCEEDED(hr))
- {
- return IsAssemblyKillBitted(pTargetAssemblyName, fileVersion);
- }
- }
-
- return false;
- }
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Determine if a specific assembly is on the killbit list
- //
-
- bool AptcaKillBitList::IsAssemblyKillBitted(IAssemblyName *pTargetAssemblyName, ULARGE_INTEGER fileVersion)
- {
- STANDARD_VM_CONTRACT;
-
- // If nothing is killbitted, then this assembly cannot be killbitted
- if (!AreAnyAssembliesKillBitted())
- {
- return false;
- }
-
- for (DWORD i = 0; i < m_killBitList.GetCount(); ++i)
- {
- IAssemblyName *pKillBitAssemblyName = reinterpret_cast<IAssemblyName *>(m_killBitList.Get(i));
-
- // By default, we compare all fields of the assembly's name, however if the culture was neutral,
- // we strip that out.
- DWORD dwCmpFlags = ASM_CMPF_IL_ALL;
-
- DWORD cbCultureSize = 0;
- SString strCulture;
- HRESULT hrCulture = pKillBitAssemblyName->GetProperty(ASM_NAME_CULTURE, NULL, &cbCultureSize);
- if (hrCulture == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- DWORD cchCulture = (cbCultureSize / sizeof(WCHAR)) - 1;
- WCHAR *wszCultureBuffer = strCulture.OpenUnicodeBuffer(cchCulture);
- hrCulture = pKillBitAssemblyName->GetProperty(ASM_NAME_CULTURE, wszCultureBuffer, &cbCultureSize);
- strCulture.CloseBuffer();
- }
-
- if (SUCCEEDED(hrCulture))
- {
- if (cbCultureSize == 0 || strCulture.EqualsCaseInsensitive(W("")) || strCulture.EqualsCaseInsensitive(W("neutral")))
- {
- dwCmpFlags &= ~ASM_CMPF_CULTURE;
- }
- }
-
- // If the input assembly matches the kill bit assembly's name and file version, then we need to
- // kill it.
- if (pTargetAssemblyName->IsEqual(pKillBitAssemblyName, dwCmpFlags) == S_OK &&
- FileVersionsAreEqual(fileVersion, pKillBitAssemblyName))
- {
- return true;
- }
- }
-
- return false;
- }
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Read the machine-wide APTCA kill bit list into a kill bit list object. For compatibility with v3.5,
- // errors during this initialization are ignored - leading to APTCA entries that may not be considered
- // for kill bitting.
- //
-
- // static
- AptcaKillBitList *AptcaKillBitList::ReadMachineKillBitList()
- {
- CONTRACT(AptcaKillBitList *)
- {
- STANDARD_VM_CHECK;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- NewHolder<AptcaKillBitList> pKillBitList(new AptcaKillBitList);
-
- HKEYHolder hKeyAptca;
-
- // Open the APTCA subkey in the registry.
- if (WszRegOpenKeyEx(HKEY_LOCAL_MACHINE, wszAptcaRootKey, 0, KEY_READ, &hKeyAptca) == ERROR_SUCCESS)
- {
-
- DWORD cchSubKeySize = 0;
- if (WszRegQueryInfoKey(hKeyAptca, NULL, NULL, NULL, NULL, &cchSubKeySize, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
- {
- cchSubKeySize = MAX_PATH_FNAME;
- }
- ++cchSubKeySize;
-
- NewArrayHolder<WCHAR> wszSubKey(new WCHAR[cchSubKeySize]);
-
- DWORD dwKey = 0;
- DWORD cchWszSubKey = cchSubKeySize;
- // Assembly specific records are represented as subkeys of the key we've just opened with names
- // equal to the strong name of the assembly being kill bitted, and a value of APTCA_FLAG = 1.
- while (WszRegEnumKeyEx(hKeyAptca, dwKey, wszSubKey, &cchWszSubKey, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
- {
- ++dwKey;
- cchWszSubKey = cchSubKeySize;
-
- // Open the subkey: the key name is the full name of the assembly to potentially kill-bit
- HKEYHolder hSubKey;
- if (WszRegOpenKeyEx(hKeyAptca, wszSubKey, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS)
- {
- continue;
- }
-
- DWORD dwKillbit = 0;
- DWORD dwType = REG_DWORD;
- DWORD dwSize = sizeof(dwKillbit);
-
- // look for the APTCA flag
- LONG queryValue = WszRegQueryValueEx(hSubKey,
- wszKillBitValue,
- NULL,
- &dwType,
- reinterpret_cast<LPBYTE>(&dwKillbit),
- &dwSize);
- if (queryValue == ERROR_SUCCESS && dwKillbit == 1)
- {
- // We have a strong named assembly with an APTCA killbit value set - parse the key into
- // an assembly name, and add it to our list
- ReleaseHolder<IAssemblyName> pKillBitAssemblyName;
- HRESULT hrAssemblyName = CreateAssemblyNameObject(&pKillBitAssemblyName, wszSubKey, CANOF_PARSE_DISPLAY_NAME, NULL);
- if (FAILED(hrAssemblyName))
- {
- continue;
- }
-
- //
- // For compatibility with v3.5, we only accept kill bit entries which have four part
- // assembly versions, names, and public key tokens.
- //
-
- // Verify the version first
- bool validVersion = true;
- for (DWORD dwVersionPartId = ASM_NAME_MAJOR_VERSION; dwVersionPartId <= ASM_NAME_REVISION_NUMBER; ++dwVersionPartId)
- {
- DWORD dwVersionPart;
- DWORD cbVersionPart = sizeof(dwVersionPart);
- HRESULT hrVersion = pKillBitAssemblyName->GetProperty(dwVersionPartId, &dwVersionPart, &cbVersionPart);
- if (FAILED(hrVersion) || cbVersionPart == 0)
- {
- validVersion = false;
- }
- }
- if (!validVersion)
- {
- continue;
- }
-
- // Make sure there is a simple name
- DWORD cbNameSize = 0;
- HRESULT hrName = pKillBitAssemblyName->GetProperty(ASM_NAME_NAME, NULL, &cbNameSize);
- if (hrName != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- continue;
- }
-
- // Verify the killbit assembly has a public key token
- DWORD cbPublicKeyTokenSize = 0;
- HRESULT hrPublicKey = pKillBitAssemblyName->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, NULL, &cbPublicKeyTokenSize);
- if (hrPublicKey != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- continue;
- }
-
- // Verify the killbit assembly has either no culture or a valid culture token
- DWORD cbCultureSize = 0;
- HRESULT hrCulture = pKillBitAssemblyName->GetProperty(ASM_NAME_CULTURE, NULL, &cbCultureSize);
- if (FAILED(hrCulture) && hrCulture != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- continue;
- }
-
- // The name checks out, so add the kill bit entry
- LOG((LF_SECURITY,
- LL_INFO10,
- "APTCA killbit added for assembly '%S'.\n",
- wszSubKey));
- pKillBitList->m_killBitList.Append(pKillBitAssemblyName.Extract());
- }
- }
- }
-
- RETURN(pKillBitList.Extract());
- }
-
- VolatilePtr<AptcaKillBitList> g_pAptcaKillBitList(NULL);
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Get the APTCA killbit list
- //
-
- AptcaKillBitList *GetKillBitList()
- {
- STANDARD_VM_CONTRACT;
-
- if (g_pAptcaKillBitList.Load() == NULL)
- {
- NewHolder<AptcaKillBitList> pAptcaKillBitList(AptcaKillBitList::ReadMachineKillBitList());
-
- LPVOID pvOldValue = InterlockedCompareExchangeT(g_pAptcaKillBitList.GetPointer(),
- pAptcaKillBitList.GetValue(),
- NULL);
- if (pvOldValue == NULL)
- {
- pAptcaKillBitList.SuppressRelease();
- }
- }
-
- _ASSERTE(g_pAptcaKillBitList.Load() != NULL);
- return g_pAptcaKillBitList.Load();
- }
-}
-
-// APTCA helper functions
-namespace
-{
- enum ConditionalAptcaSharingMode
- {
- kShareUnknown,
- kShareIfEnabled, // Share an assembly only if all conditional APTCA assemblies in its closure are enabled
- kShareIfDisabled, // Share an assembly only if all conditional APTCA assemblies in its closure are disabled
- };
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Get the name of an assembly as it would appear in the APTCA enabled list of an AppDomain
- //
-
- void GetAssemblyNameForConditionalAptca(Assembly *pAssembly, SString *pAssemblyName)
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pAssembly));
- PRECONDITION(CheckPointer(pAssemblyName));
- }
- CONTRACTL_END;
-
- GCX_COOP();
-
- // Call assembly.GetName().GetNameWithPublicKey() to get the name the user would have to add to the
- // whitelist to enable this assembly
- struct
- {
- OBJECTREF orAssembly;
- STRINGREF orAssemblyName;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.orAssembly = pAssembly->GetExposedObject();
- MethodDescCallSite getAssemblyName(METHOD__ASSEMBLY__GET_NAME_FOR_CONDITIONAL_APTCA, &gc.orAssembly);
- ARG_SLOT args[1] =
- {
- ObjToArgSlot(gc.orAssembly)
- };
- gc.orAssemblyName = getAssemblyName.Call_RetSTRINGREF(args);
-
- // Copy to assemblyName
- pAssemblyName->Set(gc.orAssemblyName->GetBuffer());
-
- GCPROTECT_END();
- }
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Determine which types of conditional APTCA assemblies may be shared
- //
-
- ConditionalAptcaSharingMode GetConditionalAptcaSharingMode()
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- static ConditionalAptcaSharingMode sharingMode = kShareUnknown;
-
- if (sharingMode == kShareUnknown)
- {
- // If the default domain has any conditional APTCA assemblies enabled in it, then we share in the
- // enabled direction. Otherwise, the default domain has all conditional APTCA assemblies disabled
- // so we need to share in the disabled direction
- ConditionalAptcaCache *pDefaultDomainCache = SystemDomain::System()->DefaultDomain()->GetSecurityDescriptor()->GetConditionalAptcaCache();
- ConditionalAptcaCache::DomainState domainState = pDefaultDomainCache->GetConditionalAptcaDomainState();
-
- if (domainState == ConditionalAptcaCache::kAllDisabled)
- {
- sharingMode = kShareIfDisabled;
- }
- else
- {
- sharingMode = kShareIfEnabled;
- }
- }
-
- return sharingMode;
- }
-
- /* XXX Fri 7/17/2009
- * I can't call DomainAssembly::IsConditionalAPTCAVisible() here. That requires an Assembly which means
- * we have to be at FILE_LOAD_ALLOCATE. There are two problems:
- * 1) We don't want to load dependencies here if we can avoid it
- * 2) We can't load them anyway (hard bound dependencies can't get past
- * FILE_LOAD_VERIFY_NATIVE_IMAGE_DEPENDENCIES.
- *
- * We're going to do a relaxed check here. Instead of checking the public key, we're
- * only going to check the public key token. See
- * code:AppDomain::IsAssemblyOnAptcaVisibleListRaw for more information.
- *
- * pAsmName - The name of the assembly to check.
- * pDomainAssembly - The Domain Assembly used for logging.
- */
- bool IsAssemblyOnAptcaVisibleList(IAssemblyName * pAsmName, DomainAssembly *pDomainAssembly)
- {
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pAsmName));
- }
- CONTRACTL_END;
-
- ConditionalAptcaCache *pDomainCache = pDomainAssembly->GetAppDomain()->GetSecurityDescriptor()->GetConditionalAptcaCache();
- if (pDomainCache->GetConditionalAptcaDomainState() == ConditionalAptcaCache::kAllEnabled)
- {
- return true;
- }
-
- CQuickBytes qbName;
- LPWSTR pszName;
- DWORD cbName = 0;
- HRESULT hr = pAsmName->GetProperty(ASM_NAME_NAME, NULL, &cbName);
- if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- pszName = (LPWSTR)qbName.AllocThrows(cbName);
- }
- else
- {
- pDomainAssembly->ExternalLog(LL_ERROR, W("Rejecting native image / code sharing because there was an ")
- W("error checking for conditional APTCA: 0x%x"), hr);
- return false;
- }
- hr = pAsmName->GetProperty(ASM_NAME_NAME, (void *)pszName, &cbName);
- if (FAILED(hr))
- {
- pDomainAssembly->ExternalLog(LL_ERROR, W("Rejecting native image / code sharing because there was an ")
- W("error checking for conditional APTCA: 0x%x"), hr);
- return false;
- }
- BYTE rgPublicKeyToken[8];
- DWORD cbPkt = _countof(rgPublicKeyToken);
- hr = pAsmName->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN,
- (void*)rgPublicKeyToken, &cbPkt);
- if (FAILED(hr))
- {
- pDomainAssembly->ExternalLog(LL_ERROR, W("Rejecting native image / code sharing because there was an ")
- W("error obtaining the public key token for %s: 0x%x"),
- pszName, hr);
- return false;
- }
-
- GCX_COOP();
-
- CLR_BOOL isVisible = FALSE;
-
- struct
- {
- OBJECTREF orThis;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
- GCPROTECT_BEGIN(gc);
- gc.orThis = pDomainAssembly->GetAppDomain()->GetExposedObject();
-
- MethodDescCallSite assemblyVisible(METHOD__APP_DOMAIN__IS_ASSEMBLY_ON_APTCA_VISIBLE_LIST_RAW,
- &gc.orThis);
- ARG_SLOT args[] = {
- ObjToArgSlot(gc.orThis),
- (ARG_SLOT)pszName,
- (ARG_SLOT)wcslen(pszName),
- (ARG_SLOT)rgPublicKeyToken,
- (ARG_SLOT)cbPkt
- };
- isVisible = assemblyVisible.Call_RetBool(args);
- GCPROTECT_END();
-
- return isVisible;
- }
-
- bool IsAssemblyOnAptcaVisibleList(DomainAssembly *pAssembly)
- {
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pAssembly));
- PRECONDITION(GetAppDomain() == pAssembly->GetAppDomain());
- }
- CONTRACTL_END;
-
- ConditionalAptcaCache *pDomainCache = pAssembly->GetAppDomain()->GetSecurityDescriptor()->GetConditionalAptcaCache();
- if (pDomainCache->GetConditionalAptcaDomainState() == ConditionalAptcaCache::kAllEnabled)
- {
- return true;
- }
-
- GCX_COOP();
-
- bool foundInList = false;
-
- // Otherwise, we need to transition into the BCL code to find out if the assembly is on the list
- struct
- {
- OBJECTREF orAppDomain;
- OBJECTREF orAssembly;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- MethodDescCallSite isAssemblyOnAptcaVisibleList(METHOD__APP_DOMAIN__IS_ASSEMBLY_ON_APTCA_VISIBLE_LIST);
- gc.orAppDomain = GetAppDomain()->GetExposedObject();
- gc.orAssembly = pAssembly->GetAssembly()->GetExposedObject();
-
- ARG_SLOT args[] =
- {
- ObjToArgSlot(gc.orAppDomain),
- ObjToArgSlot(gc.orAssembly)
- };
-
- foundInList = isAssemblyOnAptcaVisibleList.Call_RetBool(args);
-
- GCPROTECT_END();
-
- return foundInList;
- }
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Determine if an assembly is APTCA in the current domain or not
- //
- // Arguments:
- // pDomainAssembly - Assembly to check for APTCA-ness
- // tokenFlags - raw metadata security bits from the assembly
- //
- // Return Value:
- // true if the assembly is APTCA, false if it is not
- //
-
- bool IsAssemblyAptcaEnabled(DomainAssembly *pDomainAssembly, TokenSecurityDescriptorFlags tokenFlags)
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pDomainAssembly));
- }
- CONTRACTL_END;
-
-#ifdef _DEBUG
- SString strAptcaAssemblyBreak(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_Security_AptcaAssemblyBreak));
- SString strAssemblySimpleName(SString::Utf8, pDomainAssembly->GetSimpleName());
- if (strAptcaAssemblyBreak.EqualsCaseInsensitive(strAssemblySimpleName))
- {
- _ASSERTE(!"Checking APTCA-ness of an APTCA break assembly");
- }
-#endif // _DEBUG
-
- // If the assembly is not marked APTCA, then it cannot possibly be APTCA enabled
- if ((tokenFlags & TokenSecurityDescriptorFlags_APTCA) == TokenSecurityDescriptorFlags_None)
- {
- return false;
- }
-
- GCX_PREEMP();
-
- // Additionally, if the assembly is on the APTCA kill list, then no matter what it says in its metadata,
- // it should not be considered APTCA
- if (GetKillBitList()->IsAssemblyKillBitted(pDomainAssembly->GetFile()))
- {
- return false;
- }
-
- // If the assembly is conditionally APTCA, then we need to check the current AppDomain's APTCA enabled
- // list to figure out if it is APTCA in this domain.
- if (tokenFlags & TokenSecurityDescriptorFlags_ConditionalAPTCA)
- {
- return IsAssemblyOnAptcaVisibleList(pDomainAssembly);
- }
-
- // Otherwise, the assembly is APTCA
- return true;
- }
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Determine if the assembly matches the conditional APTCA sharing mode. That is, if we are sharing
- // enabled conditional APTCA assemblies check that this assembly is enabled. Similarly, if we are
- // sharing disabled conditional APTCA assemblies check that this assembly is disabled.
- //
- // This method assumes that the assembly is conditionally APTCA
- //
-
- bool AssemblyMatchesShareMode(IAssemblyName *pAsmName, DomainAssembly *pDomainAssembly)
- {
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pAsmName));
- PRECONDITION(GetConditionalAptcaSharingMode() != kShareUnknown);
- }
- CONTRACTL_END;
-
- if (IsAssemblyOnAptcaVisibleList(pAsmName, pDomainAssembly))
- {
- return GetConditionalAptcaSharingMode() == kShareIfEnabled;
- }
- else
- {
- return GetConditionalAptcaSharingMode() == kShareIfDisabled;
- }
- }
-
- bool AssemblyMatchesShareMode(ConditionalAptcaCache::State state)
- {
- STANDARD_VM_CONTRACT;
-
- _ASSERTE(state == ConditionalAptcaCache::kEnabled || state == ConditionalAptcaCache::kDisabled);
-
- if (state == ConditionalAptcaCache::kEnabled)
- {
- return GetConditionalAptcaSharingMode() == kShareIfEnabled;
- }
- else
- {
- return GetConditionalAptcaSharingMode() == kShareIfDisabled;
- }
- }
-}
-
-//------------------------------------------------------------------------------------------------------------
-//
-// Determine if the AppDomain can share an assembly or if APTCA restrictions prevent sharing
-//
-
-bool DomainCanShareAptcaAssembly(DomainAssembly *pDomainAssembly)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pDomainAssembly));
- }
- CONTRACTL_END;
-
-#ifdef _DEBUG
- DWORD dwAptcaAssemblyDomainBreak = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_Security_AptcaAssemblySharingDomainBreak);
- if (dwAptcaAssemblyDomainBreak == 0 || ADID(dwAptcaAssemblyDomainBreak) == pDomainAssembly->GetAppDomain()->GetId())
- {
- SString strAptcaAssemblySharingBreak(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_Security_AptcaAssemblySharingBreak));
- SString strAssemblySimpleName(SString::Utf8, pDomainAssembly->GetSimpleName());
-
- if (strAptcaAssemblySharingBreak.EqualsCaseInsensitive(strAssemblySimpleName))
- {
- _ASSERTE(!"Checking code sharing for APTCA break assembly");
- }
- }
-#endif // _DEBUG
-
- //
- // We can only share an assembly if all conditional APTCA assemblies in its full closure of dependencies
- // are enabled.
- //
-
- // We always allow sharing of mscorlib
- if (pDomainAssembly->IsSystem())
- {
- return true;
- }
-
- IApplicationSecurityDescriptor *pDomainSecDesc = pDomainAssembly->GetAppDomain()->GetSecurityDescriptor();
- ConditionalAptcaCache *pConditionalAptcaCache = pDomainSecDesc->GetConditionalAptcaCache();
-
- // If all assemblies in the domain match the sharing mode, then we can share the assembly
- ConditionalAptcaCache::DomainState domainState = pConditionalAptcaCache->GetConditionalAptcaDomainState();
- if (GetConditionalAptcaSharingMode() == kShareIfEnabled)
- {
- if (domainState == ConditionalAptcaCache::kAllEnabled)
- {
- return true;
- }
- }
- else
- {
- if (domainState == ConditionalAptcaCache::kAllDisabled)
- {
- return true;
- }
- }
-
- // If the root assembly is conditionally APTCA, then it needs to be enabled
- ReleaseHolder<IMDInternalImport> pRootImport(pDomainAssembly->GetFile()->GetMDImportWithRef());
- TokenSecurityDescriptorFlags rootSecurityAttributes =
- TokenSecurityDescriptor::ReadSecurityAttributes(pRootImport, TokenFromRid(1, mdtAssembly));
- if (rootSecurityAttributes & TokenSecurityDescriptorFlags_ConditionalAPTCA)
- {
- if (!AssemblyMatchesShareMode(pDomainAssembly->GetFile()->GetFusionAssemblyName(), pDomainAssembly))
- {
- return false;
- }
- }
-
- // Now we need to get the full closure of assemblies that this assembly depends upon and ensure that each
- // one of those is either not conditional APTCA or is enabled in the domain. We get a new assembly
- // closure object here rather than using DomainAssembly::GetAssemblyBindingClosure because we don't want
- // to force that closure to walk the full dependency graph (and therefore not be considered equal to
- // closures which weren't fully walked).
- IUnknown *pFusionAssembly;
- if (pDomainAssembly->GetFile()->IsIStream())
- {
- pFusionAssembly = pDomainAssembly->GetFile()->GetIHostAssembly();
- }
- else
- {
- pFusionAssembly = pDomainAssembly->GetFile()->GetFusionAssembly();
- }
-
- // Get the closure and force it to do a full dependency walk, not stopping at framework assemblies
- SafeComHolder<IAssemblyBindingClosure> pClosure;
-
-
- LPCWSTR pNIPath = NULL;
- PEAssembly *pPEAsm = pDomainAssembly->GetFile();
- if (pPEAsm->HasNativeImage())
- {
- ReleaseHolder<PEImage> pNIImage = pPEAsm->GetNativeImageWithRef();
- pNIPath = pNIImage->GetPath().GetUnicode();
- }
-
- IfFailThrow(pDomainAssembly->GetAppDomain()->GetFusionContext()->GetAssemblyBindingClosure(pFusionAssembly, pNIPath, &pClosure));
- IfFailThrow(pClosure->EnsureWalked(pFusionAssembly, pDomainAssembly->GetAppDomain()->GetFusionContext(), LEVEL_FXPROBED));
-
- // Now iterate the closure looking for conditional APTCA assemblies
- SafeComHolder<IAssemblyBindingClosureEnumerator> pClosureEnumerator;
- IfFailThrow(pClosure->EnumerateAssemblies(&pClosureEnumerator));
- LPCOLESTR szDependentAssemblyPath = NULL;
- LPCOLESTR szDependentNIAssemblyPath = NULL;
-
- for (HRESULT hr = pClosureEnumerator->GetNextAssemblyPath(&szDependentAssemblyPath, &szDependentNIAssemblyPath);
- SUCCEEDED(hr);
- hr = pClosureEnumerator->GetNextAssemblyPath(&szDependentAssemblyPath, &szDependentNIAssemblyPath))
- {
- // Make sure we've succesfully enumerated an item
- if (hr != S_OK && hr != HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS))
- {
- pDomainAssembly->ExternalLog(LL_ERROR, W("Rejecting code sharing because of an error enumerating dependent assemblies: 0x%x"), hr);
- return false;
- }
- else if (szDependentAssemblyPath == NULL)
- {
- // This means we have an assembly but no way to verify the image at this point -- should we get
- // into this state, we'll be conservative and fail the share
- pDomainAssembly->ExternalLog(LL_ERROR, W("Rejecting code sharing because an assembly in the closure does not have a path"));
- return false;
- }
- else
- {
- // We have succesfully found a new item in the closure of assemblies - now check to ensure that
- // it is either not conditionally APTCA or is enabled in tihs domain.
- PEImageHolder pDependentImage;
-
- // Use the native image if it is loaded.
- if (szDependentNIAssemblyPath != NULL)
- {
- SString strNIAssemblyPath(szDependentNIAssemblyPath);
- pDependentImage = PEImage::OpenImage(strNIAssemblyPath, MDInternalImport_OnlyLookInCache);
- if (pDependentImage != NULL && !pDependentImage->HasLoadedLayout())
- {
- pDependentImage = NULL;
- }
- else
- {
-#if FEATURE_CORECLR
-#error Coreclr needs to check native image version here.
-#endif
- }
- }
-
- if (pDependentImage == NULL)
- {
- SString strAssemblyPath(szDependentAssemblyPath);
- pDependentImage = PEImage::OpenImage(strAssemblyPath);
- }
-
- // See if we already know if this image is enabled in the current domain or not
- ConditionalAptcaCache::State dependentState = pConditionalAptcaCache->GetCachedState(pDependentImage);
-
- // We don't know this assembly's conditional APTCA state in this domain, so we need to figure it
- // out now.
- if (dependentState == ConditionalAptcaCache::kUnknown)
- {
- // First figure out if the assembly is even conditionally APTCA to begin with
- IMDInternalImport *pDependentImport = pDependentImage->GetMDImport();
- TokenSecurityDescriptorFlags dependentSecurityAttributes =
- TokenSecurityDescriptor::ReadSecurityAttributes(pDependentImport, TokenFromRid(1, mdtAssembly));
-
- if (dependentSecurityAttributes & TokenSecurityDescriptorFlags_ConditionalAPTCA)
- {
- // The the assembly name of the dependent assembly so we can check it to the domain
- // enabled list
- ReleaseHolder<IAssemblyName> pDependentAssemblyName;
- AssemblySpec dependentAssemblySpec(pDomainAssembly->GetAppDomain());
- dependentAssemblySpec.InitializeSpec(TokenFromRid(1, mdtAssembly), pDependentImport);
- IfFailThrow(dependentAssemblySpec.CreateFusionName(&pDependentAssemblyName, FALSE));
-
- // Check the domain list to see if the assembly is on it
- if (IsAssemblyOnAptcaVisibleList(pDependentAssemblyName, pDomainAssembly))
- {
- dependentState = ConditionalAptcaCache::kEnabled;
- }
- else
- {
- dependentState = ConditionalAptcaCache::kDisabled;
- }
- }
- else
- {
- // The dependent assembly doesn't have the conditional APTCA bit set on it, so we don't
- // need to do any checking to see if it's enabled
- dependentState = ConditionalAptcaCache::kNotCAptca;
- }
-
- // Cache the result of evaluating conditional APTCA on this assembly in the domain
- pConditionalAptcaCache->SetCachedState(pDependentImage, dependentState);
- }
-
- // If the dependent assembly does not match the sharing mode, then we cannot share the
- // dependency. We can always share dependencies which are not conditionally APTCA, so don't
- // bother checking the share mode for them.
- if (dependentState != ConditionalAptcaCache::kNotCAptca)
- {
- if (!AssemblyMatchesShareMode(dependentState))
- {
- pDomainAssembly->ExternalLog(LL_ERROR, W("Rejecting code sharing because a dependent assembly did not match the conditional APTCA share mode"));
- return false;
- }
- }
- }
- }
-
- // The root assembly and all of its dependents were either on the conditional APTCA list or are not
- // conditional APTCA, so we can share this assembly
- return true;
-}
-
-//------------------------------------------------------------------------------------------------------------
-//
-// Get an exception string indicating how to enable a conditional APTCA assembly if it was disabled and
-// caused an exception
-//
-
-SString GetConditionalAptcaAccessExceptionContext(Assembly *pTargetAssembly)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pTargetAssembly));
- }
- CONTRACTL_END;
-
- SString exceptionContext;
-
- ModuleSecurityDescriptor *pMSD = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pTargetAssembly);
-
- if (pMSD->GetTokenFlags() & TokenSecurityDescriptorFlags_ConditionalAPTCA)
- {
- GCX_PREEMP();
-
- if (!IsAssemblyOnAptcaVisibleList(pTargetAssembly->GetDomainAssembly()))
- {
- // We have a conditional APTCA assembly which is not on the visible list for the current
- // AppDomain, provide information on how to enable it.
- SString assemblyDisplayName;
- pTargetAssembly->GetDisplayName(assemblyDisplayName);
-
- SString assemblyConditionalAptcaName;
- GetAssemblyNameForConditionalAptca(pTargetAssembly, &assemblyConditionalAptcaName);
-
- EEException::GetResourceMessage(IDS_ACCESS_EXCEPTION_CONTEXT_CONDITIONAL_APTCA,
- exceptionContext,
- assemblyDisplayName,
- assemblyConditionalAptcaName);
- }
- }
-
- return exceptionContext;
-}
-
-//------------------------------------------------------------------------------------------------------------
-//
-// Get an exception string indicating that an assembly was on the kill bit list if it caused an exception
-//
-
-SString GetAptcaKillBitAccessExceptionContext(Assembly *pTargetAssembly)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pTargetAssembly));
- }
- CONTRACTL_END;
-
- GCX_PREEMP();
-
- SString exceptionContext;
-
- if (GetKillBitList()->IsAssemblyKillBitted(pTargetAssembly->GetDomainAssembly()->GetFile()))
- {
- SString assemblyDisplayName;
- pTargetAssembly->GetDisplayName(assemblyDisplayName);
-
- EEException::GetResourceMessage(IDS_ACCESS_EXCEPTION_CONTEXT_APTCA_KILLBIT,
- exceptionContext,
- assemblyDisplayName);
- }
-
- return exceptionContext;
-}
-
-//------------------------------------------------------------------------------------------------------------
-//
-// Determine if a native image is valid to use from the perspective of APTCA. This means that the image
-// itself and all of its dependencies must:
-// 1. Not be killbitted
-// 2. Be enabled if they are conditionally APTCA
-//
-// Arguments:
-// pNativeImage - native image to accept or reject
-// pDomainAssembly - assembly that is being loaded
-//
-// Return Value:
-// true if the native image can be accepted due to APTCA-ness, false if we need to reject it
-//
-
-bool NativeImageHasValidAptcaDependencies(PEImage *pNativeImage, DomainAssembly *pDomainAssembly)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pNativeImage));
- PRECONDITION(CheckPointer(pDomainAssembly));
- }
- CONTRACTL_END;
-
- AptcaKillBitList *pKillBitList = GetKillBitList();
-
- ConditionalAptcaCache *pDomainCache = pDomainAssembly->GetAppDomain()->GetSecurityDescriptor()->GetConditionalAptcaCache();
- // If we have any killbitted assemblies, then we need to make sure that the current assembly and its dependencies
- BOOL aptcaChecks = pKillBitList->AreAnyAssembliesKillBitted();
- BOOL conditionalAptcaChecks = pDomainCache->GetConditionalAptcaDomainState() != ConditionalAptcaCache::kAllEnabled;
- if (!aptcaChecks && !conditionalAptcaChecks)
- return true;
-
- //
- // Check to see if the NGEN image itself is APTCA and killbitted
- //
-
- ReleaseHolder<IMDInternalImport> pAssemblyMD(pDomainAssembly->GetFile()->GetMDImportWithRef());
- TokenSecurityDescriptorFlags assemblySecurityAttributes =
- TokenSecurityDescriptor::ReadSecurityAttributes(pAssemblyMD, TokenFromRid(1, mdtAssembly));
-
- if (aptcaChecks)
- {
- if ((assemblySecurityAttributes & TokenSecurityDescriptorFlags_APTCA) &&
- pKillBitList->IsAssemblyKillBitted(pDomainAssembly->GetFile()))
- {
- return false;
- }
- }
- if (conditionalAptcaChecks
- && (assemblySecurityAttributes & TokenSecurityDescriptorFlags_ConditionalAPTCA))
- {
- //
- // First check to see if we're disabled.
- //
-
- AssemblySpec spec;
- spec.InitializeSpec(pDomainAssembly->GetFile());
- ReleaseHolder<IAssemblyName> pAsmName;
- IfFailThrow(spec.CreateFusionName(&pAsmName, FALSE));
-
- if (!IsAssemblyOnAptcaVisibleList(pAsmName, pDomainAssembly))
- {
- //IsAssemblyOnAptcaVisibleList has already logged an error.
- return false;
- }
- }
-
- if (aptcaChecks || conditionalAptcaChecks)
- {
- //
- // Also check its dependencies
- //
-
- COUNT_T dependencyCount;
- PEImageLayout *pNativeLayout = pNativeImage->GetLoadedLayout();
- CORCOMPILE_DEPENDENCY *pDependencies = pNativeLayout->GetNativeDependencies(&dependencyCount);
-
- for (COUNT_T i = 0; i < dependencyCount; ++i)
- {
- CORCOMPILE_DEPENDENCY* pDependency = &(pDependencies[i]);
- // Look for any dependency which is APTCA
- if (pDependencies[i].dwAssemblyDef != mdAssemblyRefNil)
- {
- AssemblySpec name;
- name.InitializeSpec(pDependency->dwAssemblyRef,
- pNativeImage->GetNativeMDImport(),
- NULL,
- pDomainAssembly->GetFile()->IsIntrospectionOnly());
-
- ReleaseHolder<IAssemblyName> pDependencyAssemblyName;
- HRESULT hr = name.CreateFusionName(&pDependencyAssemblyName, FALSE);
-
- // If we couldn't build the assemlby name up conservatively discard the image
- if (FAILED(hr))
- {
- pDomainAssembly->ExternalLog(LL_ERROR, W("Rejecting native image because could not get ")
- W("name for assemblyref 0x%x for native image dependency: ")
- W("hr=0x%x"), pDependency->dwAssemblyRef, hr);
- return false;
- }
-
- if (pDependencies[i].dependencyInfo & (CORCOMPILE_DEPENDENCY_IS_APTCA))
- {
- ULARGE_INTEGER fileVersion;
-
- //This is a workaround for Dev10# 743602
- fileVersion.QuadPart = GET_UNALIGNED_VAL64(&(pDependencies[i].uliFileVersion));
- // If the dependency really is killbitted, then discard the image
- if (pKillBitList->IsAssemblyKillBitted(pDependencyAssemblyName, fileVersion))
- {
- pDomainAssembly->ExternalLog(LL_ERROR, W("Rejecting native image because dependency ")
- W("assemblyref 0x%x is killbitted."),
- pDependency->dwAssemblyRef);
- return false;
- }
- }
- if (pDependencies[i].dependencyInfo & (CORCOMPILE_DEPENDENCY_IS_CAPTCA))
- {
- if (!IsAssemblyOnAptcaVisibleList(pDependencyAssemblyName, pDomainAssembly))
- {
- //IsAssemblyOnAptcaVisibleList has already logged an error.
- return false;
- }
- }
- }
- }
- }
- return true;
-}
-#else // CROSSGEN_COMPILE
-namespace
-{
- bool IsAssemblyAptcaEnabled(DomainAssembly *pDomainAssembly, TokenSecurityDescriptorFlags tokenFlags)
- {
- // No killbits or conditional APTCA for crossgen. Just check whether the assembly is marked APTCA.
- return ((tokenFlags & TokenSecurityDescriptorFlags_APTCA) != TokenSecurityDescriptorFlags_None);
- }
-}
-#endif // CROSSGEN_COMPILE
-
-//------------------------------------------------------------------------------------------------------------
-//
-// Process an assembly's real APTCA flags to determine if the assembly should be considered
-// APTCA or not
-//
-// Arguments:
-// pDomainAssembly - Assembly to check for APTCA-ness
-// tokenFlags - raw metadata security bits from the assembly
-//
-// Return Value:
-// updated token security descriptor flags which indicate the assembly's true APTCA state
-//
-
-TokenSecurityDescriptorFlags ProcessAssemblyAptcaFlags(DomainAssembly *pDomainAssembly,
- TokenSecurityDescriptorFlags tokenFlags)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pDomainAssembly));
- }
- CONTRACTL_END;
-
- const TokenSecurityDescriptorFlags aptcaFlags = TokenSecurityDescriptorFlags_APTCA |
- TokenSecurityDescriptorFlags_ConditionalAPTCA;
-
- if (IsAssemblyAptcaEnabled(pDomainAssembly, tokenFlags))
- {
- // The assembly is APTCA - temporarially remove all of its APTCA bits, and then add back the
- // unconditionally APTCA bit
- tokenFlags = tokenFlags & ~aptcaFlags;
- return tokenFlags | TokenSecurityDescriptorFlags_APTCA;
- }
- else
- {
- // The assembly is not APTCA, so remove all of its APTCA bits from the token security descriptor
- return tokenFlags & ~aptcaFlags;
- }
-}
+++ /dev/null
-// 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.
-//--------------------------------------------------------------------------
-// aptca.h
-//
-// Functions for handling allow partially trusted callers assemblies
-//
-// This should be the only interface for talking about the APTCA-ness of an assembly, and even then should
-// be used only from very select areas of the CLR that absolutely need to know the information. For
-// instance:
-//
-// * the class loader (for code sharing and formatting exception messages)
-// * NGEN (for determining if a native image is valid)
-// * security attribute processing code (for obvious reasons)
-//
-// may use this interface. Nearly every other section of the code should simply be relying on the
-// ModuleSecurityDescriptor for the assembly in question. And no other sections of the code should be
-// directly asking questions like "is this assembly conditional APTCA" ... we explicitly want to hide that
-// information away behind the final assembly security attribute computation as much as possible.
-//
-// In particular, no code should be making security enforcement decisions based upon conditional APTCA, and
-// instead should rely on the existing transparency / legacy APTCA enforcement. This means that once the
-// security system, JIT, and class loader have finished setting up an assembly's APTCA attributes, there
-// should be no further questions asked about the particular APTCA attribute applied to the assembly.
-//
-// Put another way, once an assembly is loaded, the APTCA kill bit and conditional APTCA enabled / disabled
-// decision for an assembly should evaporate away, and all assemblies should look as if they either have a
-// full APTCA attribute (in the not-killbitted / conditional APTCA enabled case) or no APTCA attribute at
-// all (killbitted or conditional APTCA disabled).
-//
-
-//
-//--------------------------------------------------------------------------
-
-
-#ifndef __APTCA_H__
-#define __APTCA_H__
-
-#ifndef FEATURE_APTCA
-#error FEATURE_APTCA is required for this file
-#endif // FEATURE_APTCA
-
-#include "securitymeta.h"
-
-class ConditionalAptcaCache
-{
-public:
- typedef enum
- {
- kUnknown, // No cached state
- kEnabled, // The assembly is enabled in this domain
- kDisabled, // The assembly is disabled in this domain
- kNotCAptca, // The assembly is not conditionally APTCA
- }
- State;
-
- typedef enum
- {
- kDomainStateUnknown, // The domain state is not yet initialized
- kAllEnabled, // All assemblies in the domain are enabled
- kSomeEnabled, // Some assemblies in the domain are enabled
- kAllDisabled, // All assemblies in the domain are disabled
- }
- DomainState;
-
- ConditionalAptcaCache(AppDomain *pAppDomain);
- ~ConditionalAptcaCache();
-
- State GetCachedState(PTR_PEImage pImage);
- void SetCachedState(PTR_PEImage pImage, State state);
-
- DomainState GetConditionalAptcaDomainState();
- void SetCanonicalConditionalAptcaList(LPCWSTR wszCanonicalConditionalAptcaList);
-
- static bool ConsiderFullTrustConditionalAptcaLists();
-
-private:
- ConditionalAptcaCache(ConditionalAptcaCache &other); // not implemented - used to prevent compiler generating a copy constructor
- ConditionalAptcaCache& operator=(const ConditionalAptcaCache &other); // not implemented - used to prevent compiler generating an assignment operator
-
-private:
- AppDomain *m_pAppDomain;
-
- bool m_canonicalListIsNull;
- SString m_canonicalList;
- DomainState m_domainState;
-};
-
-// Determine if the AppDomain can share an assembly or if APTCA restrictions prevent sharing
-bool DomainCanShareAptcaAssembly(DomainAssembly *pDomainAssembly);
-
-// Get an exception string indicating how to enable a conditional APTCA assembly if it was disabled and
-// caused an exception
-SString GetConditionalAptcaAccessExceptionContext(Assembly *pTargetAssembly);
-
-// Get an exception string indicating that
-SString GetConditionalAptcaSharingExceptionContext(Assembly *pTargetAssembly);
-
-// Get an exception string indicating that an assembly was on the kill bit list if it caused an exception
-SString GetAptcaKillBitAccessExceptionContext(Assembly *pTargetAssembly);
-
-// Determine if a native image is OK to use from an APTCA perspective (it and its dependencies all have the
-// same APTCA-ness now as at NGEN time)
-bool NativeImageHasValidAptcaDependencies(PEImage *pNativeImage, DomainAssembly *pDomainAssembly);
-
-// Process an assembly's real APTCA flags to determine if the assembly should be considered APTCA or not
-TokenSecurityDescriptorFlags ProcessAssemblyAptcaFlags(DomainAssembly *pDomainAssembly, TokenSecurityDescriptorFlags tokenFlags);
-
-#endif // __APTCA_H__
}
-#ifdef FEATURE_CORECLR
if(IsSingleAppDomain())
{
SetJitHelperFunction(CORINFO_HELP_GETSHARED_GCSTATIC_BASE, JIT_GetSharedGCStaticBase_SingleAppDomain);
SetJitHelperFunction(CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_NOCTOR,JIT_GetSharedNonGCStaticBaseNoCtor_SingleAppDomain);
}
else
-#endif
if (gAppDomainTLSIndex >= TLS_MINIMUM_AVAILABLE)
{
SetJitHelperFunction(CORINFO_HELP_GETSHARED_GCSTATIC_BASE, JIT_GetSharedGCStaticBase_Portable);
#include "ngenoptout.h"
#endif
-#if !defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
-#include "assemblyusagelogmanager.h"
-#include "policy.h"
-#endif
#include "eeprofinterfaces.h"
#include "reflectclasswriter.h"
#include "peimagelayout.inl"
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-#include <shlobj.h>
-#include "eventmsg.h"
-#endif
#ifdef FEATURE_TRACELOGGING
#include "clrtracelogging.h"
#ifdef FEATURE_COMINTEROP
, m_InteropAttributeStatus(INTEROP_ATTRIBUTE_UNSET)
#endif
-#ifndef FEATURE_CORECLR
- , m_fSupportsAutoNGen(FALSE)
-#endif
{
STANDARD_VM_CONTRACT;
}
if (!m_pManifest->IsReadyToRun())
CacheManifestExportedTypes(pamTracker);
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- GenerateBreadcrumbForServicing();
-
- m_fSupportsAutoNGen = SupportsAutoNGenWorker();
-
- ReportAssemblyUse();
-#endif
#ifdef FEATURE_TRACELOGGING
}
AssemblyLoadSecurity loadSecurity;
-#ifndef FEATURE_CORECLR
- DWORD dwSpecialFlags = 0xFFFFFFFF;
-
- // Don't bother with setting up permissions if this isn't allowed to run
- // This doesn't apply in CoreCLR because you cannot specify evidence when creating a dynamic assembly
- if ((args->identity != NULL) &&
- (args->access & ASSEMBLY_ACCESS_RUN))
- {
- loadSecurity.m_pAdditionalEvidence = &args->identity;
- }
- else
- {
- if (pCallerAssembly != NULL) // can be null if caller is interop
- {
- if (args->securityContextSource == kCurrentAssembly)
- {
- IAssemblySecurityDescriptor *pCallerSecDesc = pCallerAssembly->GetSecurityDescriptor(pCallersDomain);
- gc.granted = pCallerSecDesc->GetGrantedPermissionSet(&(gc.denied));
- dwSpecialFlags = pCallerSecDesc->GetSpecialFlags();
- }
- else
- {
- IApplicationSecurityDescriptor *pCallersDomainSecDesc = pCallersDomain->GetSecurityDescriptor();
-
-#ifdef FEATURE_CAS_POLICY
- // We only want to propigate the identity of homogenous domains, since heterogenous domains tend
- // to be fully trusted even if they are housing partially trusted code - which could lead to an
- // elevation of privilege if we allow the grant set to be pushed to assemblies partially trusted
- // code is loading.
- if (!pCallersDomainSecDesc->IsHomogeneous())
- {
- COMPlusThrow(kNotSupportedException, W("NotSupported_SecurityContextSourceAppDomainInHeterogenous"));
- }
-#endif // FEATURE_CAS_POLICY
-
- gc.granted = pCallersDomainSecDesc->GetGrantedPermissionSet();
- dwSpecialFlags = pCallersDomainSecDesc->GetSpecialFlags();
- }
-
- // Caller may be in another appdomain context, in which case we'll
- // need to marshal/unmarshal the grant and deny sets across.
-#ifdef FEATURE_REMOTING // should not happen without remoting
- if (pCallersDomain != ::GetAppDomain())
- {
- gc.granted = AppDomainHelper::CrossContextCopyFrom(pCallersDomain->GetId(), &(gc.granted));
- if (gc.denied != NULL)
- {
- gc.denied = AppDomainHelper::CrossContextCopyFrom(pCallersDomain->GetId(), &(gc.denied));
- }
- }
-#else // !FEATURE_REMOTING
- _ASSERTE(pCallersDomain == ::GetAppDomain());
-#endif // FEATURE_REMOTING
- }
- }
-#else // FEATURE_CORECLR
// In SilverLight all dynamic assemblies should be transparent and partially trusted, even if they are
// created by platform assemblies. Thus they should inherit the grant sets from the appdomain not the
// parent assembly.
IApplicationSecurityDescriptor *pCurrentDomainSecDesc = ::GetAppDomain()->GetSecurityDescriptor();
gc.granted = pCurrentDomainSecDesc->GetGrantedPermissionSet();
DWORD dwSpecialFlags = pCurrentDomainSecDesc->GetSpecialFlags();
-#endif // !FEATURE_CORECLR
// If the dynamic assembly creator did not specify evidence for the newly created assembly, then it
// should inherit the grant set of the creation assembly.
if (loadSecurity.m_pAdditionalEvidence == NULL)
{
-#ifdef FEATURE_CAS_POLICY
- // If we're going to inherit the grant set of an anonymously hosted dynamic method, it will be
- // full trust/transparent. In that case, we should demand full trust.
- if(args->securityContextSource == kCurrentAssembly &&
- pCallerAssembly != NULL &&
- pCallersDomain != NULL &&
- pCallerAssembly->GetDomainAssembly(pCallersDomain) == pCallersDomain->GetAnonymouslyHostedDynamicMethodsAssembly())
- {
- loadSecurity.m_fPropagatingAnonymouslyHostedDynamicMethodGrant = true;
- }
-#endif // FEATURE_CAS_POLICY
loadSecurity.m_pGrantSet = &gc.granted;
loadSecurity.m_pRefusedSet = &gc.denied;
pAssem->m_dwDynamicAssemblyAccess = args->access;
-#ifdef FEATURE_CAS_POLICY
- // If a legacy assembly is emitting an assembly, then we implicitly add the legacy attribute. If the legacy
- // assembly is also in partial trust, we implicitly make the emitted assembly transparent.
- ModuleSecurityDescriptor *pEmittingMSD = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pCallerAssembly);
- if (pEmittingMSD->GetSecurityRuleSet() == SecurityRuleSet_Level1)
- {
- IAssemblySecurityDescriptor *pCallerSecDesc = pCallerAssembly->GetSecurityDescriptor(pCallersDomain);
- if (!pCallerSecDesc->IsFullyTrusted())
- {
- args->flags = kTransparentAssembly;
- }
- }
-
- // If the code emitting the dynamic assembly is transparent and it is attempting to emit a non-transparent
- // assembly, then we need to do a demand for the grant set of the emitting assembly (which should also be
- // is the grant set of the dynamic assembly).
- if (Security::IsMethodTransparent(pmdEmitter) && !(args->flags & kTransparentAssembly))
- {
- Security::DemandGrantSet(pCallerAssembly->GetSecurityDescriptor(pCallersDomain));
- }
-#else // FEATURE_CORECLR
// Making the dynamic assembly opportunistically critical in full trust CoreCLR and transparent otherwise.
if (!GetAppDomain()->GetSecurityDescriptor()->IsFullyTrusted())
{
args->flags = kTransparentAssembly;
}
-#endif //!FEATURE_CORECLR
// Fake up a module security descriptor for the assembly.
TokenSecurityDescriptorFlags tokenFlags = TokenSecurityDescriptorFlags_None;
if (args->flags & kTreatAsSafeAssembly)
tokenFlags |= TokenSecurityDescriptorFlags_TreatAsSafe;
-#ifdef FEATURE_APTCA
- if (args->aptcaBlob != NULL)
- {
- tokenFlags |= ParseAptcaAttribute(args->aptcaBlob->GetDirectPointerToNonObjectElements(),
- args->aptcaBlob->GetNumComponents());
- }
-#endif // FEATURE_APTCA
-
-#ifndef FEATURE_CORECLR
- // Use the security rules given to us if the emitting code has selected a specific one. Otherwise,
- // inherit the security rules of the emitting assembly.
- if (args->securityRulesBlob != NULL)
- {
- tokenFlags |= ParseSecurityRulesAttribute(args->securityRulesBlob->GetDirectPointerToNonObjectElements(),
- args->securityRulesBlob->GetNumComponents());
- }
- else
- {
- // Ensure that dynamic assemblies created by mscorlib always specify a rule set, since we want to
- // make sure that creating a level 2 assembly was an explicit decision by the emitting code,
- // rather than an implicit decision because mscorlib is level 2 itself.
- //
- // If you're seeing this assert, it means that you've created a dynamic assembly from mscorlib,
- // but did not pass a CustomAttributeBuilder for the SecurityRulesAttribute to the
- // DefineDynamicAssembly call.
- _ASSERTE(!pCallerAssembly->IsSystem());
-
- // Use the creating assembly's security rule set for the emitted assembly
- SecurityRuleSet callerRuleSet =
- ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pCallerAssembly)->GetSecurityRuleSet();
- tokenFlags |= EncodeSecurityRuleSet(callerRuleSet);
-
- tokenFlags |= TokenSecurityDescriptorFlags_SecurityRules;
- }
-#endif // !FEATURE_CORECLR
_ASSERTE(pAssem->GetManifestModule()->m_pModuleSecurityDescriptor != NULL);
pAssem->GetManifestModule()->m_pModuleSecurityDescriptor->OverrideTokenFlags(tokenFlags);
if (publicKey.GetSize() > 0)
{
pAssem->SetStrongNameLevel(Assembly::SN_PUBLIC_KEY);
-#ifndef FEATURE_CORECLR
- gc.strongNameKeyPair = args->assemblyName->GetStrongNameKeyPair();
- // If there's a public key, there might be a strong name key pair.
- if (gc.strongNameKeyPair != NULL)
- {
- MethodDescCallSite getKeyPair(METHOD__STRONG_NAME_KEY_PAIR__GET_KEY_PAIR, &gc.strongNameKeyPair);
-
- ARG_SLOT arglist[] =
- {
- ObjToArgSlot(gc.strongNameKeyPair),
- PtrToArgSlot(&gc.orArrayOrContainer)
- };
-
- BOOL bKeyInArray;
- bKeyInArray = (BOOL)getKeyPair.Call_RetBool(arglist);
-
- if (bKeyInArray)
- {
- U1ARRAYREF orArray = (U1ARRAYREF)gc.orArrayOrContainer;
- pAssem->m_cbStrongNameKeyPair = orArray->GetNumComponents();
- pAssem->m_pbStrongNameKeyPair = new BYTE[pAssem->m_cbStrongNameKeyPair];
-
- pAssem->m_FreeFlag |= pAssem->FREE_KEY_PAIR;
- memcpy(pAssem->m_pbStrongNameKeyPair, orArray->GetDataPtr(), pAssem->m_cbStrongNameKeyPair);
- pAssem->SetStrongNameLevel(Assembly::SN_FULL_KEYPAIR_IN_ARRAY);
- }
- else
- {
- STRINGREF orContainer = (STRINGREF)gc.orArrayOrContainer;
- DWORD cchContainer = orContainer->GetStringLength();
- pAssem->m_pwStrongNameKeyContainer = new WCHAR[cchContainer + 1];
-
- pAssem->m_FreeFlag |= pAssem->FREE_KEY_CONTAINER;
- memcpy(pAssem->m_pwStrongNameKeyContainer, orContainer->GetBuffer(), cchContainer * sizeof(WCHAR));
- pAssem->m_pwStrongNameKeyContainer[cchContainer] = W('\0');
-
- pAssem->SetStrongNameLevel(Assembly::SN_FULL_KEYPAIR_IN_CONTAINER);
- }
- }
- else
-#endif // FEATURE_CORECLR
{
// Since we have no way to validate the public key of a dynamic assembly we don't allow
// partial trust code to emit a dynamic assembly with an arbitrary public key.
RETURN NULL;
}
-#ifndef FEATURE_CORECLR
- // Event Tracing for Windows is used to log data for performance and functional testing purposes.
- // The events below are used to help measure the performance of assembly loading of a static reference.
- FireEtwLoaderPhaseStart((::GetAppDomain() ? ::GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable), ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderStaticLoad, NULL, NULL, GetClrInstanceId());
-#endif //!FEATURE_CORECLR
DomainAssembly * pDomainAssembly = pModule->LoadAssembly(
::GetAppDomain(),
szNamespace,
szClassName);
-#ifndef FEATURE_CORECLR
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD))
- {
- StackSString assemblySimpleName;
- EX_TRY
- {
- if ((pDomainAssembly != NULL) && (pDomainAssembly->GetCurrentAssembly() != NULL))
- {
- assemblySimpleName.AppendUTF8(pDomainAssembly->GetCurrentAssembly()->GetSimpleName());
- assemblySimpleName.Normalize(); // Ensures that the later cast to LPCWSTR does not throw.
- }
- }
- EX_CATCH
- {
- assemblySimpleName.Clear();
- }
- EX_END_CATCH(RethrowTransientExceptions)
-
- FireEtwLoaderPhaseEnd(::GetAppDomain() ? ::GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderStaticLoad, NULL, assemblySimpleName.IsEmpty() ? NULL : (LPCWSTR)assemblySimpleName, GetClrInstanceId());
- }
-#endif //!FEATURE_CORECLR
if (pDomainAssembly == NULL)
RETURN NULL;
if ((EntryType == EntryManagedMain) &&
(stringArgs == NULL)) {
- #ifndef FEATURE_CORECLR
- // If you look at the DIFF on this code then you will see a major change which is that we
- // no longer accept all the different types of data arguments to main. We now only accept
- // an array of strings.
-
- wzArgs = CorCommandLine::GetArgvW(&cCommandArgs);
- // In the WindowsCE case where the app has additional args the count will come back zero.
- if (cCommandArgs > 0) {
- if (!wzArgs)
- return E_INVALIDARG;
- }
-#else // !FEATURE_CORECLR
return E_INVALIDARG;
-#endif // !FEATURE_CORECLR
}
ETWFireEvent(Main_V1);
}
#endif // FEATURE_APPX_BINDER && FEATURE_MULTICOREJIT
-#ifdef FEATURE_CORECLR
// Set the root assembly as the assembly that is containing the main method
// The root assembly is used in the GetEntryAssembly method that on CoreCLR is used
// to get the TargetFrameworkMoniker for the app
AppDomain * pDomain = pThread->GetDomain();
pDomain->SetRootAssembly(pMeth->GetAssembly());
-#endif
hr = RunMain(pMeth, 1, &iRetVal, stringArgs);
}
}
GC_TRIGGERS;
INJECT_FAULT(COMPlusThrowOM(););
PRECONDITION(CheckPointer(refedAssembly));
-#ifdef FEATURE_CORECLR
PRECONDITION(CheckPointer(pAssemEmitter, NULL_NOT_OK));
-#else
- PRECONDITION(CheckPointer(pAssemEmitter, NULL_OK));
-#endif //FEATURE_CORECLR
POSTCONDITION(!IsNilToken(RETVAL));
POSTCONDITION(TypeFromToken(RETVAL) == mdtAssemblyRef);
}
CONTRACT_END;
SafeComHolder<IMetaDataAssemblyEmit> emitHolder;
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- if (pAssemEmitter == NULL)
- {
- pAssemEmitter = GetOnDiskMDAssemblyEmitter();
- emitHolder.Assign(pAssemEmitter);
- }
-#endif // FEATURE_CORECLR && !CROSSGEN_COMPILE
AssemblySpec spec;
spec.InitializeSpec(refedAssembly->GetManifestFile());
}
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-//***********************************************************
-//
-// get the IMetaDataAssemblyEmit for the on disk manifest.
-// Note that the pointer returned is AddRefed. It is the caller's
-// responsibility to release the reference.
-//
-//***********************************************************
-IMetaDataAssemblyEmit *Assembly::GetOnDiskMDAssemblyEmitter()
+
+HRESULT STDMETHODCALLTYPE
+GetAssembliesByName(LPCWSTR szAppBase,
+ LPCWSTR szPrivateBin,
+ LPCWSTR szAssemblyName,
+ IUnknown *ppIUnk[],
+ ULONG cMax,
+ ULONG *pcAssemblies)
{
CONTRACTL
{
- THROWS;
+ NOTHROW;
+ MODE_PREEMPTIVE;
GC_TRIGGERS;
- INJECT_FAULT(COMPlusThrowOM(););
+ INJECT_FAULT(return E_OUTOFMEMORY;);
}
CONTRACTL_END
- IMetaDataAssemblyEmit *pAssemEmitter = NULL;
- IMetaDataEmit *pEmitter;
- RefClassWriter *pRCW;
-
- _ASSERTE(m_pOnDiskManifest);
-
- pRCW = m_pOnDiskManifest->GetClassWriter();
- _ASSERTE(pRCW);
-
- // If the RefClassWriter has a on disk emitter, then use it rather than the in-memory emitter.
- pEmitter = pRCW->GetOnDiskEmitter();
-
- if (pEmitter == NULL)
- pEmitter = m_pOnDiskManifest->GetEmitter();
-
- _ASSERTE(pEmitter != NULL);
-
- IfFailThrow(pEmitter->QueryInterface(IID_IMetaDataAssemblyEmit, (void**) &pAssemEmitter));
-
- if (pAssemEmitter == NULL)
- {
- // the manifest is not writable
- _ASSERTE(!"Bad usage!");
- }
- return pAssemEmitter;
-}
-
-//***********************************************************
-//
-// prepare saving manifest to disk.
-//
-//***********************************************************
-void Assembly::PrepareSavingManifest(ReflectionModule *pAssemblyModule)
-{
- STANDARD_VM_CONTRACT;
-
- if (pAssemblyModule)
- {
- // embedded assembly
- m_pOnDiskManifest = pAssemblyModule;
- m_fEmbeddedManifest = true;
- }
- else
- {
- m_fEmbeddedManifest = false;
-
- StackSString name(SString::Utf8, GetSimpleName());
-
- // Create the module
- m_pOnDiskManifest = CreateDynamicModule(name, name, FALSE /*fIsTransient*/);
- // store the fact this on disk manifest is temporary and can be hidden from the user
- m_needsToHideManifestForEmit = TRUE;
- }
-
- NonVMComHolder<IMetaDataAssemblyEmit> pAssemblyEmit(GetOnDiskMDAssemblyEmitter());
-
- // Copy assembly metadata to emit scope
- //<TODO>@todo: add Title, Description, Alias as CA</TODO>
- // <TODO>@todo: propagate all of the information</TODO>
- // <TODO>@todo: introduce a helper in metadata to take the ansi version of string.</TODO>
-
- IMetaDataAssemblyImport *pAssemblyImport = GetManifestFile()->GetAssemblyImporter();
-
- const void *pbPublicKey;
- ULONG cbPublicKey;
- ULONG ulHashAlgId;
- LPWSTR szName;
- ULONG chName;
- ASSEMBLYMETADATA MetaData;
- DWORD dwAssemblyFlags;
-
- MetaData.cbLocale = 0;
- MetaData.ulProcessor = 0;
- MetaData.ulOS = 0;
- IfFailThrow(pAssemblyImport->GetAssemblyProps(TokenFromRid(1, mdtAssembly),
- NULL, NULL, NULL,
- NULL, 0, &chName,
- &MetaData, NULL));
- StackSString name;
- szName = name.OpenUnicodeBuffer(chName);
-
- SString locale;
- MetaData.szLocale = locale.OpenUnicodeBuffer(MetaData.cbLocale);
-
- SBuffer proc;
- MetaData.rProcessor = (DWORD *) proc.OpenRawBuffer(MetaData.ulProcessor*sizeof(*MetaData.rProcessor));
-
- SBuffer os;
- MetaData.rOS = (OSINFO *) os.OpenRawBuffer(MetaData.ulOS*sizeof(*MetaData.rOS));
-
- IfFailThrow(pAssemblyImport->GetAssemblyProps(TokenFromRid(1, mdtAssembly),
- &pbPublicKey, &cbPublicKey, &ulHashAlgId,
- szName, chName, &chName,
- &MetaData, &dwAssemblyFlags));
-
- mdAssembly ad;
- IfFailThrow(pAssemblyEmit->DefineAssembly(pbPublicKey, cbPublicKey, ulHashAlgId,
- szName, &MetaData, dwAssemblyFlags, &ad));
+ HRESULT hr = S_OK;
- SafeComHolder<IMetaDataImport> pImport;
- IfFailThrow(pAssemblyEmit->QueryInterface(IID_IMetaDataImport, (void**)&pImport));
- ULONG cExistingName = 0;
- if (FAILED(pImport->GetScopeProps(NULL, 0, &cExistingName, NULL)) || cExistingName == 0)
- {
- SafeComHolder<IMetaDataEmit> pEmit;
- IfFailThrow(pAssemblyEmit->QueryInterface(IID_IMetaDataEmit, (void**)&pEmit));
- IfFailThrow(pEmit->SetModuleProps(szName));
+ if (g_fEEInit) {
+ // Cannot call this during EE startup
+ return MSEE_E_ASSEMBLYLOADINPROGRESS;
}
- name.CloseBuffer();
- locale.CloseBuffer();
- proc.CloseRawBuffer();
- os.CloseRawBuffer();
-} // Assembly::PrepareSavingManifest
-
-
-//***********************************************************
-//
-// add a file name to the file list of this assembly. On disk only.
-//
-//***********************************************************
-mdFile Assembly::AddFile(LPCWSTR wszFileName)
-{
- STANDARD_VM_CONTRACT;
-
- SafeComHolder<IMetaDataAssemblyEmit> pAssemEmitter(GetOnDiskMDAssemblyEmitter());
- mdFile fl;
-
- // Define File.
- IfFailThrow( pAssemEmitter->DefineFile(
- wszFileName, // [IN] Name of the file.
- 0, // [IN] Hash Blob.
- 0, // [IN] Count of bytes in the Hash Blob.
- 0, // [IN] Flags.
- &fl) ); // [OUT] Returned File token.
-
- return fl;
-} // Assembly::AddFile
-
-
-//***********************************************************
-//
-// Set the hash value on a file table entry.
-//
-//***********************************************************
-void Assembly::SetFileHashValue(mdFile tkFile, LPCWSTR wszFullFileName)
-{
- STANDARD_VM_CONTRACT;
-
- SafeComHolder<IMetaDataAssemblyEmit> pAssemEmitter(GetOnDiskMDAssemblyEmitter());
+ if (!(szAssemblyName && ppIUnk && pcAssemblies))
+ return E_POINTER;
- // Get the hash value.
- SBuffer buffer;
- PEImageHolder map(PEImage::OpenImage(StackSString(wszFullFileName)));
- map->ComputeHash(GetHashAlgId(), buffer);
+ hr = COR_E_NOTSUPPORTED;
- // Set the hash blob.
- IfFailThrow( pAssemEmitter->SetFileProps(
- tkFile, // [IN] File Token.
- buffer, // [IN] Hash Blob.
- buffer.GetSize(), // [IN] Count of bytes in the Hash Blob.
- (DWORD) -1)); // [IN] Flags.
+ return hr;
+}// Used by the IMetadata API's to access an assemblies metadata.
-} // Assembly::SetHashValue
+#ifdef FEATURE_LOADER_OPTIMIZATION
-//*****************************************************************************
-// Add a Type name to the ExportedType table in the on-disk assembly manifest.
-//*****************************************************************************
-mdExportedType Assembly::AddExportedTypeOnDisk(LPCWSTR wszExportedType, mdToken tkImpl, mdToken tkTypeDef, CorTypeAttr flags)
+void Assembly::SetMissingDependenciesCheckDone()
{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE(TypeFromToken(tkTypeDef) == mdtTypeDef);
-
- // The on-disk assembly manifest
- SafeComHolder<IMetaDataAssemblyEmit> pAssemEmitter(GetOnDiskMDAssemblyEmitter());
-
- mdExportedType ct;
-
- IfFailThrow( pAssemEmitter->DefineExportedType(
- wszExportedType, // [IN] Name of the COMType.
- tkImpl, // [IN] mdFile or mdAssemblyRef that provides the ExportedType.
- tkTypeDef, // [IN] TypeDef token within the file.
- flags, // [IN] Flags.
- &ct) ); // [OUT] Returned ExportedType token.
-
- return ct;
-} // Assembly::AddExportedTypeOnDisk
+ LIMITED_METHOD_CONTRACT;
+ m_bMissingDependenciesCheckDone=TRUE;
+};
-//*******************************************************************************
-// Add a Type name to the ExportedType table in the in-memory assembly manifest.
-//*******************************************************************************
-mdExportedType Assembly::AddExportedTypeInMemory(LPCWSTR wszExportedType, mdToken tkImpl, mdToken tkTypeDef, CorTypeAttr flags)
+BOOL Assembly::MissingDependenciesCheckDone()
{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE(TypeFromToken(tkTypeDef) == mdtTypeDef);
-
- // The in-memory assembly manifest
- IMetaDataAssemblyEmit* pAssemEmitter = GetManifestFile()->GetAssemblyEmitter();
-
- mdExportedType ct;
-
- IfFailThrow( pAssemEmitter->DefineExportedType(
- wszExportedType, // [IN] Name of the COMType.
- tkImpl, // [IN] mdFile or mdAssemblyRef that provides the ExportedType.
- tkTypeDef, // [IN] TypeDef token within the file.
- flags, // [IN] Flags.
- &ct) ); // [OUT] Returned ExportedType token.
-
- return ct;
-} // Assembly::AddExportedTypeInMemory
+ LIMITED_METHOD_CONTRACT;
+ return m_bMissingDependenciesCheckDone;
+};
-//***********************************************************
-// add an entry to ManifestResource table for a stand alone managed resource. On disk only.
-//***********************************************************
-void Assembly::AddStandAloneResource(LPCWSTR wszName, LPCWSTR wszDescription, LPCWSTR wszMimeType, LPCWSTR wszFileName, LPCWSTR wszFullFileName, int iAttribute)
+#ifdef FEATURE_FUSION
+void Assembly::SetBindingClosure(IAssemblyBindingClosure* pClosure) // Addrefs. It is assumed the caller did not addref pClosure for us.
{
- STANDARD_VM_CONTRACT;
-
- SafeComHolder<IMetaDataAssemblyEmit> pAssemEmitter(GetOnDiskMDAssemblyEmitter());
- mdFile tkFile;
- mdManifestResource mr;
- SBuffer hash;
-
- // Get the hash value;
- if (GetHashAlgId())
+ CONTRACTL
{
- PEImageHolder pImage(PEImage::OpenImage(StackSString(wszFullFileName)));
- pImage->ComputeHash(GetHashAlgId(), hash);
+ THROWS;
+ GC_NOTRIGGER;
+ INJECT_FAULT(COMPlusThrowOM(););
}
+ CONTRACTL_END;
- IfFailThrow( pAssemEmitter->DefineFile(
- wszFileName, // [IN] Name of the file.
- hash, // [IN] Hash Blob.
- hash.GetSize(), // [IN] Count of bytes in the Hash Blob.
- ffContainsNoMetaData, // [IN] Flags.
- &tkFile) ); // [OUT] Returned File token.
-
-
- IfFailThrow( pAssemEmitter->DefineManifestResource(
- wszName, // [IN] Name of the resource.
- tkFile, // [IN] mdFile or mdAssemblyRef that provides the resource.
- 0, // [IN] Offset to the beginning of the resource within the file.
- iAttribute, // [IN] Flags.
- &mr) ); // [OUT] Returned ManifestResource token.
-
-} // Assembly::AddStandAloneResource
+ _ASSERTE(m_pBindingClosure == NULL);
+ _ASSERTE(pClosure != NULL);
+ m_pBindingClosure = pClosure;
+ pClosure->AddRef(); // It is assumed the caller did not addref pBindingClosure for us.
+}
-//***********************************************************
-// Save security permission requests.
-//***********************************************************
-void Assembly::AddDeclarativeSecurity(DWORD dwAction, void const *pValue, DWORD cbValue)
+IAssemblyBindingClosure * Assembly::GetBindingClosure()
{
- STANDARD_VM_CONTRACT;
-
- mdAssembly tkAssembly = 0x20000001;
-
- SafeComHolder<IMetaDataAssemblyEmit> pAssemEmitter(GetOnDiskMDAssemblyEmitter());
- _ASSERTE( pAssemEmitter );
-
- SafeComHolder<IMetaDataEmitHelper> pEmitHelper;
- IfFailThrow( pAssemEmitter->QueryInterface(IID_IMetaDataEmitHelper, (void**)&pEmitHelper) );
-
- IfFailThrow(pEmitHelper->AddDeclarativeSecurityHelper(tkAssembly,
- dwAction,
- pValue,
- cbValue,
- NULL));
+ LIMITED_METHOD_CONTRACT;
+ return m_pBindingClosure;
}
-//***********************************************************
-// Allocate space for a strong name signature in the manifest
-//***********************************************************
-HRESULT Assembly::AllocateStrongNameSignature(ICeeFileGen *pCeeFileGen,
- HCEEFILE ceeFile)
+// The shared module list is effectively an extension of the shared domain assembly hash table.
+// It is the canonical list and aribiter of modules loaded from this assembly by any app domain.
+// Modules are stored here immediately on creating (to prevent duplicate creation), as opposed to
+// in the rid map, where they are only placed upon load completion.
+
+BOOL Assembly::CanBeShared(DomainAssembly *pDomainAssembly)
{
CONTRACTL
{
- NOTHROW;
+ PRECONDITION(CheckPointer(pDomainAssembly));
+ THROWS;
GC_TRIGGERS;
- MODE_PREEMPTIVE;
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END
-
- HRESULT hr;
- HCEESECTION TData;
- DWORD dwDataOffset;
- DWORD dwDataLength;
- DWORD dwDataRVA;
- VOID *pvBuffer;
- const void *pbPublicKey;
- ULONG cbPublicKey;
-
- // Determine size of signature blob.
-
- IfFailRet(GetManifestImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly),
- &pbPublicKey, &cbPublicKey, NULL,
- NULL, NULL, NULL));
-
- if (!StrongNameSignatureSize((BYTE *) pbPublicKey, cbPublicKey, &dwDataLength)) {
- hr = StrongNameErrorInfo();
- return hr;
+ INJECT_FAULT(COMPlusThrowOM(););
}
-
- // Allocate space for the signature in the text section and update the COM+
- // header to point to the space.
- IfFailRet(pCeeFileGen->GetIlSection(ceeFile, &TData));
- IfFailRet(pCeeFileGen->GetSectionDataLen(TData, &dwDataOffset));
- IfFailRet(pCeeFileGen->GetSectionBlock(TData, dwDataLength, 4, &pvBuffer));
- IfFailRet(pCeeFileGen->GetMethodRVA(ceeFile, dwDataOffset, &dwDataRVA));
- IfFailRet(pCeeFileGen->SetStrongNameEntry(ceeFile, dwDataLength, dwDataRVA));
-
- return S_OK;
-}
+ CONTRACTL_END;
+ LOG((LF_CODESHARING,
+ LL_INFO100,
+ "Checking if we can share: \"%S\" in domain 0x%x.\n",
+ GetDebugName(), pDomainAssembly->GetAppDomain()));
-//***********************************************************
-// Strong name sign a manifest already persisted to disk
-//***********************************************************
-HRESULT Assembly::SignWithStrongName(LPCWSTR wszFileName)
-{
- CONTRACTL
+ STRESS_LOG2(LF_CODESHARING, LL_INFO1000,"Checking whether DomainAssembly %p is compatible with Assembly %p",
+ pDomainAssembly,this);
+
+ // We must always share the same system assemblies
+ if (IsSystem())
{
- NOTHROW;
- GC_TRIGGERS;
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END
-
- HRESULT hr = S_OK;
-
- // If we're going to do a full signing we have a key pair either
- // in a key container or provided directly in a byte array.
-
- switch (m_eStrongNameLevel) {
- case SN_FULL_KEYPAIR_IN_ARRAY:
- if (!StrongNameSignatureGeneration(wszFileName, NULL, m_pbStrongNameKeyPair, m_cbStrongNameKeyPair, NULL, NULL))
- hr = StrongNameErrorInfo();
- break;
-
- case SN_FULL_KEYPAIR_IN_CONTAINER:
- if (!StrongNameSignatureGeneration(wszFileName, m_pwStrongNameKeyContainer, NULL, 0, NULL, NULL))
- hr = StrongNameErrorInfo();
- break;
-
- default:
- break;
- }
-
- return hr;
-}
-
-
-//***********************************************************
-// save the manifest to disk!
-//***********************************************************
-void Assembly::SaveManifestToDisk(LPCWSTR wszFileName, int entrypoint, int fileKind, DWORD corhFlags, DWORD peFlags)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = NOERROR;
- HCEEFILE ceeFile = NULL;
- ICeeFileGen *pCeeFileGen = NULL;
- RefClassWriter *pRCW;
- IMetaDataEmit *pEmitter;
-
- _ASSERTE( m_fEmbeddedManifest == false );
-
- pRCW = m_pOnDiskManifest->GetClassWriter();
- _ASSERTE(pRCW);
-
- IfFailGo( pRCW->EnsureCeeFileGenCreated(corhFlags, peFlags) );
-
- pCeeFileGen = pRCW->GetCeeFileGen();
- ceeFile = pRCW->GetHCEEFILE();
- _ASSERTE(ceeFile && pCeeFileGen);
-
- //Emit the MetaData
- pEmitter = m_pOnDiskManifest->GetClassWriter()->GetEmitter();
- IfFailGo( pCeeFileGen->EmitMetaDataEx(ceeFile, pEmitter) );
-
- // Allocate space for a strong name signature if a public key was supplied
- // (this doesn't strong name the assembly, but it makes it possible to do so
- // as a post processing step).
- if (IsStrongNamed())
- IfFailGo(AllocateStrongNameSignature(pCeeFileGen, ceeFile));
-
- IfFailGo( pCeeFileGen->SetOutputFileName(ceeFile, (LPWSTR)wszFileName) );
-
- // the entryPoint for an assembly is a tkFile token if exist.
- if (RidFromToken(entrypoint) != mdTokenNil)
- IfFailGo( pCeeFileGen->SetEntryPoint(ceeFile, entrypoint) );
- if (fileKind == Dll)
- {
- pCeeFileGen->SetDllSwitch(ceeFile, true);
- }
- else
- {
- // should have a valid entry point for applications
- if (fileKind == WindowApplication)
- {
- IfFailGo( pCeeFileGen->SetSubsystem(ceeFile, IMAGE_SUBSYSTEM_WINDOWS_GUI, CEE_IMAGE_SUBSYSTEM_MAJOR_VERSION, CEE_IMAGE_SUBSYSTEM_MINOR_VERSION) );
- }
- else
- {
- _ASSERTE(fileKind == ConsoleApplication);
- IfFailGo( pCeeFileGen->SetSubsystem(ceeFile, IMAGE_SUBSYSTEM_WINDOWS_CUI, CEE_IMAGE_SUBSYSTEM_MAJOR_VERSION, CEE_IMAGE_SUBSYSTEM_MINOR_VERSION) );
- }
-
- }
-
- //Generate the CeeFile
- IfFailGo(pCeeFileGen->GenerateCeeFile(ceeFile) );
-
- // Strong name sign the resulting assembly if required.
- if (IsStrongNamed())
- IfFailGo(SignWithStrongName(wszFileName));
-
- // now release the m_pOnDiskManifest
-ErrExit:
- pRCW->DestroyCeeFileGen();
-
- // we keep the on disk manifest so that the GetModules code can skip over this ad-hoc module when modules are enumerated.
- // Need to see if we can remove the creation of this module alltogether
- //m_pOnDiskManifest = NULL;
-
- if (FAILED(hr))
- {
- if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
- {
- if (IsWin32IOError(HRESULT_CODE(hr)))
- {
- COMPlusThrowHR(COR_E_IO);
- }
- else
- {
- COMPlusThrowHR(hr);
- }
- }
- if (hr == CEE_E_CVTRES_NOT_FOUND)
- COMPlusThrow(kIOException, W("Argument_cvtres_NotFound"));
- COMPlusThrowHR(hr);
- }
-} // Assembly::SaveManifestToDisk
-
-#endif // FEATURE_CORECLR && !CROSSGEN_COMPILE
-
-
-HRESULT STDMETHODCALLTYPE
-GetAssembliesByName(LPCWSTR szAppBase,
- LPCWSTR szPrivateBin,
- LPCWSTR szAssemblyName,
- IUnknown *ppIUnk[],
- ULONG cMax,
- ULONG *pcAssemblies)
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_PREEMPTIVE;
- GC_TRIGGERS;
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END
-
- HRESULT hr = S_OK;
-
- if (g_fEEInit) {
- // Cannot call this during EE startup
- return MSEE_E_ASSEMBLYLOADINPROGRESS;
- }
-
- if (!(szAssemblyName && ppIUnk && pcAssemblies))
- return E_POINTER;
-
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
- hr = COR_E_NOTSUPPORTED;
-#else
- AppDomain *pDomain = NULL;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr)
- if(szAppBase || szPrivateBin)
- {
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
- MethodDescCallSite createDomainEx(METHOD__APP_DOMAIN__CREATE_DOMAINEX);
- struct _gc {
- STRINGREF pFriendlyName;
- STRINGREF pAppBase;
- STRINGREF pPrivateBin;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- gc.pFriendlyName = StringObject::NewString(W("GetAssembliesByName"));
-
- if(szAppBase)
- {
- gc.pAppBase = StringObject::NewString(szAppBase);
- }
-
- if(szPrivateBin)
- {
- gc.pPrivateBin = StringObject::NewString(szPrivateBin);
- }
-
- ARG_SLOT args[5] =
- {
- ObjToArgSlot(gc.pFriendlyName),
- NULL,
- ObjToArgSlot(gc.pAppBase),
- ObjToArgSlot(gc.pPrivateBin),
- BoolToArgSlot(false)
- };
- APPDOMAINREF pDom = (APPDOMAINREF) createDomainEx.Call_RetOBJECTREF(args);
- if (pDom == NULL)
- {
- hr = E_FAIL;
- }
- else
- {
- Context *pContext = CRemotingServices::GetServerContextForProxy((OBJECTREF) pDom);
- _ASSERTE(pContext);
- pDomain = pContext->GetDomain();
- }
-
- GCPROTECT_END();
- }
- else
- pDomain = SystemDomain::System()->DefaultDomain();
-
- Assembly *pFoundAssembly;
- if (SUCCEEDED(hr)) {
- pFoundAssembly = pDomain->LoadAssemblyHelper(szAssemblyName,
- NULL);
- if (SUCCEEDED(hr)) {
- if (cMax < 1)
- hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
- else {
- ppIUnk[0] = (IUnknown *)pFoundAssembly->GetManifestAssemblyImporter();
- ppIUnk[0]->AddRef();
- }
- *pcAssemblies = 1;
- }
- }
-
- END_EXTERNAL_ENTRYPOINT;
-#endif // FEATURE_CORECLR
-
- return hr;
-}// Used by the IMetadata API's to access an assemblies metadata.
-
-#ifdef FEATURE_LOADER_OPTIMIZATION
-
-void Assembly::SetMissingDependenciesCheckDone()
-{
- LIMITED_METHOD_CONTRACT;
- m_bMissingDependenciesCheckDone=TRUE;
-};
-
-BOOL Assembly::MissingDependenciesCheckDone()
-{
- LIMITED_METHOD_CONTRACT;
- return m_bMissingDependenciesCheckDone;
-};
-
-
-#ifdef FEATURE_FUSION
-void Assembly::SetBindingClosure(IAssemblyBindingClosure* pClosure) // Addrefs. It is assumed the caller did not addref pClosure for us.
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- _ASSERTE(m_pBindingClosure == NULL);
- _ASSERTE(pClosure != NULL);
-
- m_pBindingClosure = pClosure;
- pClosure->AddRef(); // It is assumed the caller did not addref pBindingClosure for us.
-}
-
-IAssemblyBindingClosure * Assembly::GetBindingClosure()
-{
- LIMITED_METHOD_CONTRACT;
- return m_pBindingClosure;
-}
-
-
-// The shared module list is effectively an extension of the shared domain assembly hash table.
-// It is the canonical list and aribiter of modules loaded from this assembly by any app domain.
-// Modules are stored here immediately on creating (to prevent duplicate creation), as opposed to
-// in the rid map, where they are only placed upon load completion.
-
-BOOL Assembly::CanBeShared(DomainAssembly *pDomainAssembly)
-{
- CONTRACTL
- {
- PRECONDITION(CheckPointer(pDomainAssembly));
- THROWS;
- GC_TRIGGERS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- LOG((LF_CODESHARING,
- LL_INFO100,
- "Checking if we can share: \"%S\" in domain 0x%x.\n",
- GetDebugName(), pDomainAssembly->GetAppDomain()));
-
- STRESS_LOG2(LF_CODESHARING, LL_INFO1000,"Checking whether DomainAssembly %p is compatible with Assembly %p",
- pDomainAssembly,this);
-
- // We must always share the same system assemblies
- if (IsSystem())
- {
- STRESS_LOG0(LF_CODESHARING, LL_INFO1000,"System assembly - sharing");
- return TRUE;
+ STRESS_LOG0(LF_CODESHARING, LL_INFO1000,"System assembly - sharing");
+ return TRUE;
}
if ((pDomainAssembly->GetDebuggerInfoBits()&~(DACF_PDBS_COPIED|DACF_IGNORE_PDBS|DACF_OBSOLETE_TRACK_JIT_INFO))
#endif // FEATURE_COMINTEROP
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-void Assembly::GenerateBreadcrumbForServicing()
-{
- STANDARD_VM_CONTRACT;
-
- if (AppX::IsAppXProcess() || IsIntrospectionOnly() || GetManifestFile()->IsDynamic())
- {
- return;
- }
-
- if (HasServiceableAttribute() || IsExistingOobAssembly())
- {
- StackSString ssDisplayName;
- GetDisplayName(ssDisplayName);
-
- WriteBreadcrumb(ssDisplayName);
- CheckDenyList(ssDisplayName);
- }
-}
-
-void Assembly::WriteBreadcrumb(const SString &ssDisplayName)
-{
- STANDARD_VM_CONTRACT;
-
- WCHAR path[MAX_LONGPATH];
- HRESULT hr = WszSHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, ARRAYSIZE(path), path);
- if (hr != S_OK)
- {
- return;
- }
-
- if (wcscat_s(path, W("\\Microsoft\\NetFramework\\BreadcrumbStore\\")) != 0)
- {
- return;
- }
-
- size_t dirPathLen = wcslen(path);
-
- // Validate the display name. E.g., we don't want the display name to start with "..\\".
- bool inSimpleName = true;
- for (SString::CIterator it = ssDisplayName.Begin(); it != ssDisplayName.End(); ++it)
- {
- WCHAR c = *it;
-
- // The following characters are always allowed: a-zA-Z0-9_
- if (c >= W('a') && c <= W('z') || c >= W('A') && c <= W('Z') || c >= W('0') && c <= W('9') || c == W('_')) continue;
-
- // The period is allowed except as the first char.
- if (c == W('.') && it != ssDisplayName.Begin()) continue;
-
- // A comma terminates the assembly simple name, and we are in key=value portion of the display name.
- if (c == W(','))
- {
- inSimpleName = false;
- continue;
- }
-
- // In key=value portion, space and equal sign are also allowed.
- if (!inSimpleName && (c == W(' ') || c == W('='))) continue;
-
- // If we reach here, we have an invalid assembly display name. Return without writing breadcrumb.
- return;
- }
-
- // Log a breadcrumb using full display name.
- if (wcscat_s(path, ssDisplayName.GetUnicode()) == 0)
- {
- HandleHolder hFile = WszCreateFile(path, 0, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
- }
-
- // Log another breadcrumb using display name without version.
- // First make a copy of the display name, and look for its version part.
- StackSString ssNoVersion(ssDisplayName);
- SString::Iterator itVersion = ssNoVersion.Begin();
- if (!ssNoVersion.Find(itVersion, W(", Version=")))
- {
- return;
- }
-
- // Start from the comma before Version=, advance past the comma, then look for the next comma.
- SString::Iterator itVersionEnd = itVersion;
- ++itVersionEnd;
- if (!ssNoVersion.Find(itVersionEnd, W(',')))
- {
- // Version is the last key=value pair.
- itVersionEnd = ssNoVersion.End();
- }
-
- // Erase the version.
- ssNoVersion.Delete(itVersion, itVersionEnd - itVersion);
-
- // Generate the full path string and create the file.
- path[dirPathLen] = W('\0');
- if (wcscat_s(path, ssNoVersion.GetUnicode()) == 0)
- {
- HandleHolder hFile = WszCreateFile(path, 0, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
- }
-
-}
-
-bool Assembly::HasServiceableAttribute()
-{
- STANDARD_VM_CONTRACT;
-
- IMDInternalImport *pImport = GetManifestImport();
- MDEnumHolder hEnum(pImport);
- HRESULT hr = pImport->EnumCustomAttributeByNameInit(GetManifestToken(), ASSEMBLY_METADATA_TYPE, &hEnum);
- if (hr != S_OK)
- {
- return false;
- }
-
- mdCustomAttribute tkAttribute;
- while (pImport->EnumNext(&hEnum, &tkAttribute))
- {
- // Get raw custom attribute.
- const BYTE *pbAttr = NULL; // Custom attribute data as a BYTE*.
- ULONG cbAttr = 0; // Size of custom attribute data.
- if (FAILED(pImport->GetCustomAttributeAsBlob(tkAttribute, reinterpret_cast<const void **>(&pbAttr), &cbAttr)))
- {
- THROW_BAD_FORMAT(BFA_INVALID_TOKEN, GetManifestModule());
- }
-
- CustomAttributeParser cap(pbAttr, cbAttr);
- if (FAILED(cap.ValidateProlog()))
- {
- THROW_BAD_FORMAT(BFA_BAD_CA_HEADER, GetManifestModule());
- }
-
- // Get the metadata key. It is not null terminated.
- LPCUTF8 key;
- ULONG cbKey;
- if (FAILED(cap.GetString(&key, &cbKey)))
- {
- THROW_BAD_FORMAT(BFA_BAD_CA_HEADER, GetManifestModule());
- }
-
- const LPCUTF8 szServiceable = "Serviceable";
- const ULONG cbServiceable = 11;
- if (cbKey != cbServiceable || strncmp(key, szServiceable, cbKey) != 0)
- {
- continue;
- }
-
- // Get the metadata value. It is not null terminated.
- if (FAILED(cap.GetString(&key, &cbKey)))
- {
- THROW_BAD_FORMAT(BFA_BAD_CA_HEADER, GetManifestModule());
- }
-
- const LPCUTF8 szTrue = "True";
- const ULONG cbTrue = 4;
- if (cbKey == cbTrue && strncmp(key, szTrue, cbKey) == 0)
- {
- return true;
- }
- }
-
- return false;
-}
-
-bool Assembly::IsExistingOobAssembly()
-{
- WRAPPER_NO_CONTRACT;
-
- return ExistingOobAssemblyList::Instance()->IsOnlist(this);
-}
-
-void Assembly::CheckDenyList(const SString &ssDisplayName)
-{
- STANDARD_VM_CONTRACT;
-
- StackSString ssKeyName(W("SOFTWARE\\Microsoft\\.NETFramework\\Policy\\DenyList\\"));
-
- ssKeyName.Append(ssDisplayName);
-
- RegKeyHolder hKey;
- LONG status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ssKeyName.GetUnicode(), 0, KEY_WOW64_64KEY | GENERIC_READ, &hKey);
-
- if (status != ERROR_SUCCESS)
- {
- return;
- }
-
- StackSString ssFwlink;
- HRESULT hr = Clr::Util::Reg::ReadStringValue(hKey, NULL, NULL, ssFwlink);
- if (FAILED(hr) || ssFwlink.GetCount() == 0)
- {
- ssFwlink.Set(W("http://go.microsoft.com/fwlink/?LinkID=286319"));
- }
-
- StackSString ssMessageTemplate;
- if(!ssMessageTemplate.LoadResource(CCompRC::Optional, IDS_EE_ASSEMBLY_ON_DENY_LIST))
- {
- ssMessageTemplate.Set(W("The assembly %1 that the application tried to load has a known vulnerability. Please go to %2 to find a fix for this issue."));
- }
-
- StackSString ssMessage;
- ssMessage.FormatMessage(FORMAT_MESSAGE_FROM_STRING, ssMessageTemplate.GetUnicode(), 0, 0, ssDisplayName, ssFwlink);
-
- ClrReportEvent(
- W(".NET Runtime"), // Event source
- EVENTLOG_ERROR_TYPE, // Type
- 0, // Category
- SecurityConfig, // Event ID
- NULL, // User SID
- ssMessage.GetUnicode()); // Message
-
- NewHolder<EEMessageException> pEx(new EEMessageException(kSecurityException, IDS_EE_ASSEMBLY_ON_DENY_LIST, ssDisplayName.GetUnicode(), ssFwlink.GetUnicode()));
- EEFileLoadException::Throw(m_pManifestFile, pEx->GetHR(), pEx);
-}
-
-BOOL IsReportableAssembly(PEAssembly *pPEAssembly)
-{
- STANDARD_VM_CONTRACT;
-
- // If the assembly could have used a native image, but did not, report the IL image
- BOOL fCanUseNativeImage = (pPEAssembly->HasHostAssembly() || pPEAssembly->IsContextLoad()) &&
- pPEAssembly->CanUseNativeImage() &&
- !IsNativeImageOptedOut(pPEAssembly->GetFusionAssemblyName());
-
- return fCanUseNativeImage;
-}
-
-BOOL Assembly::SupportsAutoNGenWorker()
-{
- STANDARD_VM_CONTRACT;
-
- PEAssembly *pPEAssembly = GetManifestFile();
-
- if (pPEAssembly->IsSourceGAC() && Fusion::Util::IsUnifiedAssembly(pPEAssembly->GetFusionAssemblyName()) == S_OK)
- {
- // Assemblies in the .NET Framework supports Auto NGen.
- return TRUE;
- }
-
- if (IsAfContentType_WindowsRuntime(GetFlags()))
- {
- // WinMD files support Auto NGen.
- return TRUE;
- }
-
- if (pPEAssembly->HasHostAssembly())
- {
- // Auto NGen is enabled on all Metro app assemblies.
- return TRUE;
- }
-
- if (pPEAssembly->IsSourceGAC())
- {
- // For non-framework assemblies in GAC, look for TargetFrameworkAttriute.
- const BYTE *pbAttr; // Custom attribute data as a BYTE*.
- ULONG cbAttr; // Size of custom attribute data.
- HRESULT hr = GetManifestImport()->GetCustomAttributeByName(GetManifestToken(), TARGET_FRAMEWORK_TYPE, (const void**)&pbAttr, &cbAttr);
- if (hr != S_OK)
- {
- return FALSE;
- }
-
- CustomAttributeParser cap(pbAttr, cbAttr);
- if (FAILED(cap.ValidateProlog()))
- {
- THROW_BAD_FORMAT(BFA_BAD_CA_HEADER, GetManifestModule());
- }
- LPCUTF8 lpTargetFramework;
- ULONG cbTargetFramework;
- if (FAILED(cap.GetString(&lpTargetFramework, &cbTargetFramework)))
- {
- THROW_BAD_FORMAT(BFA_BAD_CA_HEADER, GetManifestModule());
- }
-
- if (lpTargetFramework == NULL || cbTargetFramework == 0)
- {
- return FALSE;
- }
-
- SString ssTargetFramework(SString::Utf8, lpTargetFramework, cbTargetFramework);
-
- // Look for two special TargetFramework values that disables AutoNGen. To guard against future
- // variations of the string values, we do prefix matches.
- SString ssFramework40(SString::Literal, W(".NETFramework,Version=v4.0"));
- SString ssPortableLib(SString::Literal, W(".NETPortable,"));
- if (ssTargetFramework.BeginsWithCaseInsensitive(ssFramework40) || ssTargetFramework.BeginsWithCaseInsensitive(ssPortableLib))
- {
- return FALSE;
- }
-
- // If TargetFramework doesn't match one of the two special values, we enable Auto NGen.
- return TRUE;
- }
-
- return FALSE;
-}
-
-void Assembly::ReportAssemblyUse()
-{
- STANDARD_VM_CONTRACT;
-
- // Do not log if we don't have a global gac logger object
- if (g_pIAssemblyUsageLogGac != NULL)
- {
- // Only consider reporting for loads that could possibly use native images.
- PEAssembly *pPEAssembly = this->GetManifestFile();
- if (IsReportableAssembly(pPEAssembly) && !pPEAssembly->IsReportedToUsageLog())
- {
- // Do not log repeatedly
- pPEAssembly->SetReportedToUsageLog();
-
- ReleaseHolder<IAssemblyUsageLog> pRefCountedUsageLog;
- IAssemblyUsageLog *pUsageLog = NULL;
- if (SupportsAutoNGen())
- {
- if (pPEAssembly->IsSourceGAC())
- {
- pUsageLog = g_pIAssemblyUsageLogGac;
- }
- else if (pPEAssembly->HasHostAssembly())
- {
- UINT_PTR binderId;
- IfFailThrow(pPEAssembly->GetHostAssembly()->GetBinderID(&binderId));
- pRefCountedUsageLog = AssemblyUsageLogManager::GetUsageLogForBinder(binderId);
- pUsageLog = pRefCountedUsageLog;
- }
- }
-
- if (pUsageLog)
- {
- PEAssembly *pPEAssembly = GetManifestFile();
- StackSString name;
- // GAC Assemblies are reported by assembly name
- if (pUsageLog == g_pIAssemblyUsageLogGac)
- {
- this->GetDisplayName(name);
- }
- // Other assemblies (AppX...) are reported by file path
- else
- {
- name.Set(pPEAssembly->GetILimage()->GetPath().GetUnicode());
- }
-
- if (pPEAssembly->HasNativeImage())
- {
- if(!IsSystem())
- {
- // If the assembly used a native image, report it
- ReleaseHolder<PEImage> pNativeImage = pPEAssembly->GetNativeImageWithRef();
- pUsageLog->LogFile(name.GetUnicode(), pNativeImage->GetPath().GetUnicode(), ASSEMBLY_USAGE_LOG_FLAGS_NI);
- }
- }
- else
- {
- // If the assembly could have used a native image, but did not, report the IL image
- pUsageLog->LogFile(name.GetUnicode(), NULL, ASSEMBLY_USAGE_LOG_FLAGS_IL);
- }
- }
- }
- }
-}
-#endif // FEATURE_CORECLR && !CROSSGEN_COMPILE
#endif // #ifndef DACCESS_COMPILE
// CoreCLR does not have a valid scenario for strong-named assemblies requiring their dependencies
// to be strong-named as well.
-#if !defined(FEATURE_CORECLR)
- // If this assembly has a strong name, then its friends declarations need to have strong names too
- if (pAssembly->IsStrongNamed())
- {
-#ifdef FEATURE_FUSION
- DWORD dwSize = 0;
- if (SUCCEEDED(hr = pFriendAssemblyName->GetProperty(ASM_NAME_PUBLIC_KEY, NULL, &dwSize)))
- {
- // If this call succeeds with an empty buffer, then the supplied name doesn't have a public key.
- THROW_HR_ERROR_WITH_INFO(META_E_CA_FRIENDS_SN_REQUIRED, pAssembly);
- }
- else if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- IfFailThrow(hr);
- }
-#else // FEATURE_FUSION
- // Desktop crossgen comes here
- if (!pFriendAssemblyName->IsStrongNamed())
- {
- // If this call succeeds with an empty buffer, then the supplied name doesn't have a public key.
- THROW_HR_ERROR_WITH_INFO(META_E_CA_FRIENDS_SN_REQUIRED, pAssembly);
- }
-#endif // FEATURE_FUSION
- }
-#endif // !defined(FEATURE_CORECLR)
pFriendAssemblies->AddFriendAssembly(pFriendAssemblyName);
#endif // !DACCESS_COMPILE
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE) && !defined(DACCESS_COMPILE)
-
-ExistingOobAssemblyList::ExistingOobAssemblyList()
-{
- STANDARD_VM_CONTRACT;
-
- RegKeyHolder hKey;
- LONG status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, W("SOFTWARE\\Microsoft\\.NETFramework\\Policy\\Servicing"), 0, KEY_WOW64_64KEY | GENERIC_READ, &hKey);
- if (status != ERROR_SUCCESS)
- {
- return;
- }
-
- for (DWORD i = 0; ; i++)
- {
- WCHAR name[MAX_PATH_FNAME + 1];
- DWORD cchName = ARRAYSIZE(name);
- status = RegEnumKeyExW(hKey, i, name, &cchName, NULL, NULL, NULL, NULL);
-
- if (status == ERROR_NO_MORE_ITEMS)
- {
- break;
- }
-
- if (status == ERROR_SUCCESS)
- {
- NonVMComHolder<IAssemblyName> pAssemblyName;
- HRESULT hr = CreateAssemblyNameObject(&pAssemblyName, name, CANOF_PARSE_DISPLAY_NAME, NULL);
- if (SUCCEEDED(hr))
- {
- hr = m_alExistingOobAssemblies.Append(pAssemblyName.GetValue());
- if (SUCCEEDED(hr))
- {
- pAssemblyName.SuppressRelease();
- }
- }
- }
- }
-}
-
-bool ExistingOobAssemblyList::IsOnlist(Assembly *pAssembly)
-{
- STANDARD_VM_CONTRACT;
-
- ArrayList::Iterator itAssemblyNames = m_alExistingOobAssemblies.Iterate();
- while (itAssemblyNames.Next())
- {
- IAssemblyName *pAssemblyName = static_cast<IAssemblyName *>(itAssemblyNames.GetElement());
- HRESULT hr = pAssemblyName->IsEqual(pAssembly->GetFusionAssemblyName(), ASM_CMPF_DEFAULT);
- if (hr == S_OK)
- {
- return true;
- }
- }
-
- return false;
-}
-
-void ExistingOobAssemblyList::Init()
-{
- STANDARD_VM_CONTRACT;
-
- s_pInstance = new ExistingOobAssemblyList();
-}
-
-ExistingOobAssemblyList *ExistingOobAssemblyList::s_pInstance;
-#endif // !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE) && !defined(DACCESS_COMPILE)
BOOL GetModuleZapFile(LPCWSTR name, SString &path);
-#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_CORESYSTEM)
BOOL AllowUntrustedCaller();
-#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#endif // defined(FEATURE_CORESYSTEM)
#ifdef LOGGING
LPCWSTR GetDebugName()
void AddType(Module* pModule,
mdTypeDef cl);
void AddExportedType(mdExportedType cl);
-#ifndef FEATURE_CORECLR
- void PrepareSavingManifest(ReflectionModule *pAssemblyModule);
- mdFile AddFile(LPCWSTR wszFileName);
- void SetFileHashValue(mdFile tkFile, LPCWSTR wszFullFileName);
-#endif
mdAssemblyRef AddAssemblyRef(Assembly *refedAssembly, IMetaDataAssemblyEmit *pAssemEmitter = NULL, BOOL fUsePublicKeyToken = TRUE);
-#ifndef FEATURE_CORECLR
- mdExportedType AddExportedTypeOnDisk(LPCWSTR wszExportedType, mdToken tkImpl, mdToken tkTypeDef, CorTypeAttr flags);
- mdExportedType AddExportedTypeInMemory(LPCWSTR wszExportedType, mdToken tkImpl, mdToken tkTypeDef, CorTypeAttr flags);
- void AddStandAloneResource(LPCWSTR wszName, LPCWSTR wszDescription, LPCWSTR wszMimeType, LPCWSTR wszFileName, LPCWSTR wszFullFileName, int iAttribute);
- void SaveManifestToDisk(LPCWSTR wszFileName, int entrypoint, int fileKind, DWORD corhFlags, DWORD peFlags);
-#endif // FEATURE_CORECLR
-#ifndef FEATURE_CORECLR
- void AddDeclarativeSecurity(DWORD dwAction, void const *pValue, DWORD cbValue);
-
- IMetaDataAssemblyEmit *GetOnDiskMDAssemblyEmitter();
-#endif // FEATURE_CORECLR
//****************************************************************************************
IWinMDImport *GetManifestWinMDImport();
#endif
-#ifndef FEATURE_CORECLR
- BOOL SupportsAutoNGen()
- {
- WRAPPER_NO_CONTRACT;
- return m_fSupportsAutoNGen;
- }
-#endif
protected:
void CacheFriendAssemblyInfo();
-#ifndef FEATURE_CORECLR
- void GenerateBreadcrumbForServicing();
- void WriteBreadcrumb(const SString &ssDisplayName);
- bool HasServiceableAttribute();
- bool IsExistingOobAssembly();
- void CheckDenyList(const SString &ssDisplayName);
-
- BOOL SupportsAutoNGenWorker();
-#endif
PTR_BaseDomain m_pDomain; // Parent Domain
PTR_ClassLoader m_pClassLoader; // Single Loader
DWORD m_dwReliabilityContract;
-#ifndef FEATURE_CORECLR
- BOOL m_fSupportsAutoNGen;
-#endif
};
typedef Assembly::ModuleIterator ModuleIterator;
return IsAssemblyOnList(pAccessingAssembly, m_alFullAccessFriendAssemblies);
}
-#ifndef FEATURE_CORECLR
- //------------------------------------------------------------------------------
- // It is undesirable to reintroduce the concept of inquiring about friendship without specifying a member or type
- // but necessary for TP. In case of doubt, it's safer to return "true" as this won't affect
- // correctness (but might cause unnecessary ngen's when updating assemblies.)
- //------------------------------------------------------------------------------
- bool MightGrantFriendAccessTo(PEAssembly *pAccessingAssembly)
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- PRECONDITION(CheckPointer(pAccessingAssembly));
- }
- CONTRACTL_END;
-
- return IsAssemblyOnList(pAccessingAssembly, m_alFullAccessFriendAssemblies);
- }
-#endif // !FEATURE_CORECLR
bool IgnoresAccessChecksTo(Assembly *pAccessedAssembly)
{
#endif // !DACCESS_COMPILE
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-class ExistingOobAssemblyList
-{
-public:
-#ifndef DACCESS_COMPILE
- ExistingOobAssemblyList();
-
- bool IsOnlist(Assembly *pAssembly);
-
- static void Init();
- static ExistingOobAssemblyList *Instance() { return s_pInstance; }
-#endif
-
-private:
- ArrayList m_alExistingOobAssemblies;
-
- // The single instance of this class:
- static ExistingOobAssemblyList *s_pInstance;
-};
-#endif // !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
#endif
EX_TRY
{
-#ifdef FEATURE_CORECLR
// Allow AssemblyLoadContext.GetAssemblyName for native images on CoreCLR
if (pImage->HasNTHeaders() && pImage->HasCorHeader() && pImage->HasNativeHeader())
pImage->VerifyIsNIAssembly();
else
pImage->VerifyIsAssembly();
-#else
- pImage->VerifyIsAssembly();
-#endif
}
EX_CATCH
{
AssemblySpec spec;
spec.InitializeSpec(TokenFromRid(mdtAssembly,1),pImage->GetMDImport(),NULL,TRUE);
-#ifndef FEATURE_CORECLR
- spec.SetCodeBase(sUrl);
-#endif
spec.AssemblyNameInit(&gc.result, pImage);
HELPER_METHOD_FRAME_END();
}
FCIMPLEND
-#ifndef FEATURE_CORECLR
-FCIMPL1(Object*, AssemblyNameNative::EscapeCodeBase, StringObject* filenameUNSAFE)
-{
- FCALL_CONTRACT;
-
- STRINGREF rv = NULL;
- STRINGREF filename = (STRINGREF) filenameUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_RET_1(filename);
-
- LPWSTR pCodeBase = NULL;
- DWORD dwCodeBase = 0;
- CQuickBytes qb;
-
- if (filename != NULL) {
- WCHAR* pString;
- int iString;
- filename->RefInterpretGetStringValuesDangerousForGC(&pString, &iString);
- dwCodeBase = (DWORD) iString;
- pCodeBase = (LPWSTR) qb.AllocThrows((++dwCodeBase) * sizeof(WCHAR));
- memcpy(pCodeBase, pString, dwCodeBase*sizeof(WCHAR));
- }
-
- if(pCodeBase) {
- CQuickBytes qb2;
- DWORD dwEscaped = 1;
-
- DWORD flags = 0;
- if (RunningOnWin7())
- flags |= URL_ESCAPE_AS_UTF8;
-
- UrlEscape(pCodeBase, (LPWSTR) qb2.Ptr(), &dwEscaped, flags);
-
- LPWSTR result = (LPWSTR)qb2.AllocThrows((++dwEscaped) * sizeof(WCHAR));
- HRESULT hr = UrlEscape(pCodeBase, result, &dwEscaped, flags);
-
- if (SUCCEEDED(hr))
- rv = StringObject::NewString(result);
- else
- COMPlusThrowHR(hr);
- }
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(rv);
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
FCIMPL4(void, AssemblyNameNative::Init, Object * refThisUNSAFE, OBJECTREF * pAssemblyRef, CLR_BOOL fForIntrospection, CLR_BOOL fRaiseResolveEvent)
{
if (pCallersAssembly == NULL) {
pCallersAssembly = SystemDomain::System()->SystemAssembly();
} else {
-#ifdef FEATURE_CAS_POLICY
- // If no evidence was provided to the Assembly.Load(byte[]) call,
- // we want to inherit the evidence from the security context source
- if (fPropagateIdentity) {
- ISecurityDescriptor *pSecDesc = NULL;
- if (securityContextSource == kCurrentAppDomain) {
- pSecDesc = pCallersDomain->GetSecurityDescriptor();
- }
- else {
- _ASSERTE(securityContextSource == kCurrentAssembly);
- pSecDesc = pCallersAssembly->GetSecurityDescriptor(pCallersDomain);
- }
-
- ENTER_DOMAIN_PTR(pSecDesc->GetDomain(),ADV_RUNNINGIN)
- {
- gc.orefSecurity = pSecDesc->GetEvidence();
- }
- END_DOMAIN_TRANSITION;
-
- // Caller may be in another appdomain context, in which case we'll
- // need to marshal/unmarshal the evidence across.
-#ifdef FEATURE_REMOTING // should not happenwithout remoting
- if (pCallersDomain != GetAppDomain())
- gc.orefSecurity = AppDomainHelper::CrossContextCopyFrom(pCallersDomain->GetId(), &gc.orefSecurity);
-#else
- _ASSERTE(pCallersDomain == GetAppDomain());
-#endif
- }
-#endif // FEATURE_CAS_POLICY
}
if ((COUNT_T)uAssemblyLength !=uAssemblyLength) // overflow
{
DWORD dwSpecialFlags = 0;
-#ifdef FEATURE_CAS_POLICY
- if (securityContextSource == kCurrentAssembly)
- {
- IAssemblySecurityDescriptor *pCallersSecDesc = pCallersAssembly->GetSecurityDescriptor(pCallersDomain);
- gc.granted = pCallersSecDesc->GetGrantedPermissionSet( &(gc.denied));
- dwSpecialFlags = pCallersSecDesc->GetSpecialFlags();
-
- // If we're going to inherit the grant set of an anonymously hosted dynamic method, it will be
- // full trust/transparent. In that case, we should demand full trust.
- if(pCallersAssembly != NULL && pCallersDomain != NULL && pCallersAssembly->GetDomainAssembly(pCallersDomain) == pCallersDomain->GetAnonymouslyHostedDynamicMethodsAssembly())
- {
- loadSecurity.m_fPropagatingAnonymouslyHostedDynamicMethodGrant = true;
- }
- }
- else
-#endif // FEATURE_CAS_POLICY
{
IApplicationSecurityDescriptor *pDomainSecDesc = pCallersDomain->GetSecurityDescriptor();
-#ifdef FEATURE_CAS_POLICY
- // We only want to propigate the identity of homogenous domains, since heterogenous domains tend
- // to be fully trusted even if they are housing partially trusted code - which could lead to an
- // elevation of privilege if we allow the grant set to be pushed to assemblies partially trusted
- // code is loading.
- if (!pDomainSecDesc->IsHomogeneous())
- {
- COMPlusThrow(kNotSupportedException, W("NotSupported_SecurityContextSourceAppDomainInHeterogenous"));
- }
-#endif // FEATURE_CAS_POLICY
gc.granted = pDomainSecDesc->GetGrantedPermissionSet();
}
#endif // FEATURE_FUSION
-#ifdef FEATURE_CAS_POLICY
-BOOL QCALLTYPE AssemblyNative::IsStrongNameVerified(QCall::AssemblyHandle pAssembly)
-{
- QCALL_CONTRACT;
-
- BOOL fStrongNameVerified = FALSE;
-
- BEGIN_QCALL;
-
- PEFile *pPEFile = pAssembly->GetFile();
- fStrongNameVerified = pPEFile->IsStrongNameVerified();
-
- END_QCALL;
-
- return fStrongNameVerified;
-}
-#endif // FEATURE_CAS_POLICY
#ifdef FEATURE_APPX
/*static*/
static
INT32 QCALLTYPE GetHashAlgorithm(QCall::AssemblyHandle pAssembly);
-#ifndef FEATURE_CORECLR
- static
- BYTE QCALLTYPE GetSecurityRuleSet(QCall::AssemblyHandle pAssembly);
-#endif // !FEATURE_CORECLR
static
void QCALLTYPE GetSimpleName(QCall::AssemblyHandle pAssembly, QCall::StringHandleOnStack retSimpleName);
static FCDECL1(ReflectModuleBaseObject *, GetOnDiskAssemblyModule, AssemblyBaseObject * pAssemblyUNSAFE);
static FCDECL1(ReflectModuleBaseObject *, GetInMemoryAssemblyModule, AssemblyBaseObject * pAssemblyUNSAFE);
-#ifndef FEATURE_CORECLR
- static
- FCDECL1(FC_BOOL_RET, IsGlobalAssemblyCache, AssemblyBaseObject* pAssemblyUNSAFE);
-#endif // !FEATURE_CORECLR
static
void QCALLTYPE GetGrantSet(QCall::AssemblyHandle pAssembly, QCall::ObjectHandleOnStack retGranted, QCall::ObjectHandleOnStack retDenied);
static
INT64 QCALLTYPE GetHostContext(QCall::AssemblyHandle pAssembly);
-#ifdef FEATURE_CAS_POLICY
- static
- BOOL QCALLTYPE IsStrongNameVerified(QCall::AssemblyHandle pAssembly);
-#endif // FEATURE_CAS_POLICY
//
// AssemblyBuilder FCALLs
static
void QCALLTYPE PrepareForSavingManifestToDisk(QCall::AssemblyHandle pAssembly, QCall::ModuleHandle pAssemblyModule);
-#ifndef FEATURE_CORECLR
- static
- void QCALLTYPE SaveManifestToDisk(QCall::AssemblyHandle pAssembly,
- LPCWSTR wszManifestFileName,
- INT32 entrypoint,
- INT32 fileKind,
- INT32 portableExecutableKind,
- INT32 imageFileMachine);
-
- static
- mdExportedType QCALLTYPE AddExportedTypeOnDisk(QCall::AssemblyHandle pAssembly, LPCWSTR wzzCOMTypeName, INT32 tkImpl, INT32 tkTypeDef, INT32 flags);
-
- static
- mdExportedType QCALLTYPE AddExportedTypeInMemory(QCall::AssemblyHandle pAssembly, LPCWSTR wzzCOMTypeName, INT32 tkImpl, INT32 tkTypeDef, INT32 flags);
-
-#endif // FEATURE_CORECLR
static
mdFile QCALLTYPE AddFile(QCall::AssemblyHandle pAssembly, LPCWSTR wszFileName);
static
void QCALLTYPE AddDeclarativeSecurity(QCall::AssemblyHandle pAssembly, INT32 action, PVOID blob, INT32 length);
-#ifndef FEATURE_CORECLR
- static
- void QCALLTYPE CreateVersionInfoResource(LPCWSTR pwzFilename,
- LPCWSTR pwzTitle,
- LPCWSTR pwzIconFilename,
- LPCWSTR pwzDescription,
- LPCWSTR pwzCopyright,
- LPCWSTR pwzTrademark,
- LPCWSTR pwzCompany,
- LPCWSTR pwzProduct,
- LPCWSTR pwzProductVersion,
- LPCWSTR pwzFileVersion,
- INT32 lcid,
- BOOL fIsDll,
- QCall::StringHandleOnStack retFileName);
-#endif // !FEATURE_CORECLR
static
void QCALLTYPE GetRawBytes(QCall::AssemblyHandle pAssembly, QCall::ObjectHandleOnStack retRawBytes);
if (pStaticParent != NULL)
{
// We dont validate this for CoreCLR as there is no good use-case for this scenario.
-#if !defined(FEATURE_CORECLR)
- // It is OK for signed assemblies to reference WinRT assemblies (.winmd files) that are not signed
- if (!IsContentType_WindowsRuntime() && pStaticParent->GetFile()->IsStrongNamed() && !IsStrongNamed())
- {
- ThrowHR(FUSION_E_PRIVATE_ASM_DISALLOWED);
- }
-#endif // !defined(FEATURE_CORECLR)
SetParentAssembly(pStaticParent);
}
}
#endif //FEATURE_COMINTEROP
-#if defined(FEATURE_CORECLR)
// Set the binding context for the AssemblySpec
ICLRPrivBinder* pCurrentBinder = GetBindingContext();
ICLRPrivBinder* pExpectedBinder = pFile->GetBindingContext();
_ASSERTE((pExpectedBinder != NULL) || pFile->IsSystem() || pFile->IsDynamic());
SetBindingContext(pExpectedBinder);
}
-#endif // defined(FEATURE_CORECLR)
}
#ifndef CROSSGEN_COMPILE
return pDomainAssembly->GetAssembly();
}
-#if defined(FEATURE_CORECLR)
// Returns a BOOL indicating if the two Binder references point to the same
// binder instance.
BOOL AreSameBinderInstance(ICLRPrivBinder *pBinderA, ICLRPrivBinder *pBinderB)
return fIsSameInstance;
}
-#endif // defined(FEATURE_CORECLR)
ICLRPrivBinder* AssemblySpec::GetBindingContextFromParentAssembly(AppDomain *pDomain)
{
ETWOnStartup (LoaderCatchCall_V1, LoaderCatchCallEnd_V1);
AppDomain* pDomain = GetAppDomain();
-#ifndef FEATURE_CORECLR
- // Event Tracing for Windows is used to log data for performance and functional testing purposes.
- // The events in this function are used to help measure the performance of assembly loading as a whole for dynamic loads.
-
- // Special-purpose holder structure to ensure the LoaderPhaseEnd ETW event is fired when returning from function.
- struct ETWLoaderPhaseHolder
- {
- StackSString ETWCodeBase, ETWAssemblyName;
-
- DWORD _dwAppDomainId;
- BOOL initialized;
-
- ETWLoaderPhaseHolder()
- : _dwAppDomainId(ETWAppDomainIdNotAvailable)
- , initialized(FALSE)
- { }
-
- void Init(DWORD dwAppDomainId, LPCWSTR wszCodeBase, LPCSTR szAssemblyName)
- {
- _dwAppDomainId = dwAppDomainId;
-
- EX_TRY
- {
- if (wszCodeBase != NULL)
- {
- ETWCodeBase.Append(wszCodeBase);
- ETWCodeBase.Normalize(); // Ensures that the later cast to LPCWSTR does not throw.
- }
- }
- EX_CATCH
- {
- ETWCodeBase.Clear();
- }
- EX_END_CATCH(RethrowTransientExceptions)
-
- EX_TRY
- {
- if (szAssemblyName != NULL)
- {
- ETWAssemblyName.AppendUTF8(szAssemblyName);
- ETWAssemblyName.Normalize(); // Ensures that the later cast to LPCWSTR does not throw.
- }
- }
- EX_CATCH
- {
- ETWAssemblyName.Clear();
- }
- EX_END_CATCH(RethrowTransientExceptions)
-
- FireEtwLoaderPhaseStart(_dwAppDomainId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderDynamicLoad, ETWCodeBase.IsEmpty() ? NULL : (LPCWSTR)ETWCodeBase, ETWAssemblyName.IsEmpty() ? NULL : (LPCWSTR)ETWAssemblyName, GetClrInstanceId());
-
- initialized = TRUE;
- }
-
- ~ETWLoaderPhaseHolder()
- {
- if (initialized)
- {
- FireEtwLoaderPhaseEnd(_dwAppDomainId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderDynamicLoad, ETWCodeBase.IsEmpty() ? NULL : (LPCWSTR)ETWCodeBase, ETWAssemblyName.IsEmpty() ? NULL : (LPCWSTR)ETWAssemblyName, GetClrInstanceId());
- }
- }
- };
-
- ETWLoaderPhaseHolder loaderPhaseHolder;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
-#ifdef FEATURE_FUSION
- loaderPhaseHolder.Init(pDomain->GetId().m_dwId, m_wszCodeBase, m_pAssemblyName);
-#else
- loaderPhaseHolder.Init(pDomain->GetId().m_dwId, NULL, NULL);
-#endif
- }
-#endif // FEATURE_CORECLR
DomainAssembly *pAssembly = nullptr;
m_pHeap = pHeap;
}
-#if defined(FEATURE_CORECLR)
AssemblySpecBindingCache::AssemblyBinding* AssemblySpecBindingCache::GetAssemblyBindingEntryForAssemblySpec(AssemblySpec* pSpec, BOOL fThrow)
{
CONTRACTL
return pEntry;
}
-#endif // defined(FEATURE_CORECLR)
BOOL AssemblySpecBindingCache::Contains(AssemblySpec *pSpec)
{
WRAPPER_NO_CONTRACT;
-#if !defined(FEATURE_CORECLR)
- DWORD key = pSpec->Hash();
- AssemblyBinding *entry = (AssemblyBinding *) m_map.LookupValue(key, pSpec);
- return (entry != (AssemblyBinding *) INVALIDENTRY);
-#else // defined(FEATURE_CORECLR)
return (GetAssemblyBindingEntryForAssemblySpec(pSpec, TRUE) != (AssemblyBinding *) INVALIDENTRY);
-#endif // !defined(FEATURE_CORECLR)
}
DomainAssembly *AssemblySpecBindingCache::LookupAssembly(AssemblySpec *pSpec,
AssemblyBinding *entry = (AssemblyBinding *) INVALIDENTRY;
-#if !defined(FEATURE_CORECLR)
- DWORD key = pSpec->Hash();
- entry = (AssemblyBinding *) m_map.LookupValue(key, pSpec);
-#else // defined(FEATURE_CORECLR)
entry = GetAssemblyBindingEntryForAssemblySpec(pSpec, fThrow);
-#endif // !defined(FEATURE_CORECLR)
if (entry == (AssemblyBinding *) INVALIDENTRY)
RETURN NULL;
AssemblyBinding *entry = (AssemblyBinding *) INVALIDENTRY;
-#if !defined(FEATURE_CORECLR)
- DWORD key = pSpec->Hash();
- entry = (AssemblyBinding *) m_map.LookupValue(key, pSpec);
-#else // defined(FEATURE_CORECLR)
entry = GetAssemblyBindingEntryForAssemblySpec(pSpec, fThrow);
-#endif // !defined(FEATURE_CORECLR)
if (entry == (AssemblyBinding *) INVALIDENTRY)
RETURN NULL;
UPTR key = (UPTR)pSpec->Hash();
-#if defined(FEATURE_CORECLR)
// On CoreCLR, we will use the BinderID as the key
ICLRPrivBinder* pBinderContextForLookup = pAssembly->GetFile()->GetBindingContext();
_ASSERTE(pBinderContextForLookup || pAssembly->GetFile()->IsSystem());
pSpec->SetBindingContext(pBinderContextForLookup);
}
}
-#endif // defined(FEATURE_CORECLR)
AssemblyBinding *entry = (AssemblyBinding *) m_map.LookupValue(key, pSpec);
UPTR key = (UPTR)pSpec->Hash();
-#if defined(FEATURE_CORECLR)
// On CoreCLR, we will use the BinderID as the key
ICLRPrivBinder* pBinderContextForLookup = pFile->GetBindingContext();
_ASSERTE(pBinderContextForLookup || pFile->IsSystem());
pSpec->SetBindingContext(pBinderContextForLookup);
}
}
-#endif // defined(FEATURE_CORECLR)
AssemblyBinding *entry = (AssemblyBinding *) m_map.LookupValue(key, pSpec);
UPTR key = (UPTR)pSpec->Hash();
-#if !defined(FEATURE_CORECLR)
- AssemblyBinding *entry = (AssemblyBinding *) m_map.LookupValue(key, pSpec);
-#else // defined(FEATURE_CORECLR)
AssemblyBinding *entry = GetAssemblyBindingEntryForAssemblySpec(pSpec, TRUE);
if (entry == (AssemblyBinding *) INVALIDENTRY)
{
}
}
}
-#endif // defined(FEATURE_CORECLR)
if (entry == (AssemblyBinding *) INVALIDENTRY) {
AssemblyBindingHolder abHolder;
HRESULT hr=InitializeSpecInternal(kAssemblyRefOrDef, pImport,pStaticParent,fIntrospectionOnly,TRUE);
if(FAILED(hr))
EEFileLoadException::Throw(this,hr);
-#ifndef FEATURE_CORECLR
- CloneFields();
-#endif
};
#ifdef FEATURE_FUSION
BOOL fNgenExplicitBind = FALSE,
BOOL fExplicitBindToNativeImage = FALSE,
StackCrawlMark *pCallerStackMark = NULL );
-#ifndef FEATURE_CORECLR
- static VOID BindToSystem(BINDER_SPACE::Assembly** ppAssembly);
-#endif
#endif
Assembly *LoadAssembly(FileLoadLevel targetLevel,
PtrHashMap m_map;
LoaderHeap *m_pHeap;
-#if defined(FEATURE_CORECLR)
AssemblySpecBindingCache::AssemblyBinding* GetAssemblyBindingEntryForAssemblySpec(AssemblySpec* pSpec, BOOL fThrow);
-#endif // defined(FEATURE_CORECLR)
public:
return pSpec->Hash();
}
-#if defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE)
+#if !defined(DACCESS_COMPILE)
void GetAllAssemblies(SetSHash<PTR_DomainAssembly>& assemblyList)
{
PtrHashMap::PtrIterator i = m_map.begin();
( (iNameLen == CoreLibNameLen) || (m_pAssemblyName[CoreLibNameLen] == ',') ) ) ) );
}
-#ifdef FEATURE_CORECLR
BOOL BaseAssemblySpec::IsAssemblySpecForMscorlib()
{
CONTRACTL
}
#define MSCORLIB_PUBLICKEY g_rbTheSilverlightPlatformKey
-#else
-#define MSCORLIB_PUBLICKEY g_rbNeutralPublicKey
-#endif
// A satellite assembly for mscorlib is named "mscorlib.resources" or
ICLRPrivBinder *m_pHostBinder;
int m_ownedFlags;
BOOL m_fIntrospectionOnly;
-#if defined(FEATURE_CORECLR)
ICLRPrivBinder *m_pBindingContext;
-#endif // defined(FEATURE_CORECLR)
public:
enum
VOID CloneFieldsToLoaderHeap(int flags, LoaderHeap *pHeap, AllocMemTracker *pamTracker);
VOID CloneFieldsToStackingAllocator(StackingAllocator* alloc);
-#if defined(FEATURE_CORECLR)
inline void SetBindingContext(ICLRPrivBinder *pBindingContext)
{
LIMITED_METHOD_CONTRACT;
}
BOOL IsAssemblySpecForMscorlib();
-#endif // defined(FEATURE_CORECLR)
HRESULT ParseName();
DWORD Hash();
extern LocaleID g_lcid;
-#if defined(FEATURE_CORECLR)
BOOL AreSameBinderInstance(ICLRPrivBinder *pBinderA, ICLRPrivBinder *pBinderB);
-#endif // defined(FEATURE_CORECLR)
inline int BaseAssemblySpec::CompareStrings(LPCUTF8 string1, LPCUTF8 string2)
{
m_pHostBinder = pSpec->m_pHostBinder;
-#ifdef FEATURE_CORECLR
if ((pSpec->m_ownedFlags & BAD_NAME_OWNED) != 0)
{
m_ownedFlags |= BAD_NAME_OWNED;
}
-#endif
#ifdef FEATURE_FUSION
IAssemblyName* pNameAfterPolicy=pSpec->GetNameAfterPolicy();
}
#endif
-#if defined(FEATURE_CORECLR)
m_pBindingContext = pSpec->m_pBindingContext;
-#endif // defined(FEATURE_CORECLR)
}
MODE_ANY;
} CONTRACTL_END;
-#ifdef FEATURE_CORECLR
if(m_wszCodeBase)
return HashString(m_wszCodeBase);
-#endif
// Hash fields.
DWORD hash = 0;
hash ^= m_dwFlags;
hash = _rotl(hash, 4);
-#ifndef FEATURE_CORECLR
- if (m_wszCodeBase)
- hash ^= HashString(m_wszCodeBase);
- hash = _rotl(hash, 4);
-#endif
hash ^= m_context.usMajorVersion;
hash = _rotl(hash, 8);
{
WRAPPER_NO_CONTRACT;
-#ifndef FEATURE_CORECLR
- _ASSERTE(pSpec != NULL);
-
- if ((m_dwFlags & afContentType_Mask) == (pSpec->m_dwFlags & afContentType_Mask))
- {
- if (IsContentType_WindowsRuntime() && pSpec->IsContentType_WindowsRuntime())
- {
- // If comparing assembly definitions, can not use bindability attributes as
- // a shortcut for equivalence, as this type of shortcut is only applicable
- // when comparing assembly references (not definitions).
- //
- // Example of why this is needed: native images still need to compare
- // assembly identities even if they are not bindable, because it needs to
- // ensure that the exact same assembly file (definition) is used at runtime
- // as was used during compilation.
- if ((dwCompareFlags & ASC_DefinitionEquality) != ASC_DefinitionEquality)
- {
- // WinRT assembly references are meaningless, they are all equal to each other
- return TRUE;
- }
- }
- }
- else
- {
- return FALSE;
- }
-#endif
-#ifdef FEATURE_CORECLR
if(m_wszCodeBase || pSpec->m_wszCodeBase)
{
if(!m_wszCodeBase || !pSpec->m_wszCodeBase)
return FALSE;
return wcscmp(m_wszCodeBase,(pSpec->m_wszCodeBase))==0;
}
-#endif
// Compare fields
#ifdef FEATURE_FUSION
|| memcmp(m_pbPublicKeyOrToken, pSpec->m_pbPublicKeyOrToken, m_cbPublicKeyOrToken))
return FALSE;
-#ifndef FEATURE_CORECLR
- if (m_wszCodeBase != pSpec->m_wszCodeBase
- && (m_wszCodeBase == NULL || pSpec->m_wszCodeBase == NULL
- || wcscmp(m_wszCodeBase, pSpec->m_wszCodeBase)))
- return FALSE;
-#endif
if (m_dwFlags != pSpec->m_dwFlags)
return FALSE;
}
#endif
-#if defined(FEATURE_CORECLR)
// If the assemblySpec contains the binding context, then check if they match.
if (!(pSpec->IsAssemblySpecForMscorlib() && IsAssemblySpecForMscorlib()))
{
return FALSE;
}
}
-#endif // defined(FEATURE_CORECLR)
return TRUE;
SafeComHolder<ISymUnmanagedBinder> pBinder;
-#if defined(FEATURE_CORECLR)
if (g_pDebugInterface == NULL)
{
// @TODO: this is reachable when debugging!
UNREACHABLE_MSG("About to CoCreateInstance! This code should not be "
"reachable or needs to be reimplemented for CoreCLR!");
}
-#endif // FEATURE_CORECLR
if (this->GetInMemorySymbolStreamFormat() == eSymbolFormatILDB)
{
// On desktop, the framework installer is supposed to install diasymreader.dll as well
// and so this shouldn't happen.
hr = FakeCoCreateInstanceEx(CLSID_CorSymBinder_SxS,
-#ifdef FEATURE_CORECLR
NATIVE_SYMBOL_READER_DLL,
-#else
- GetInternalSystemDirectory(),
-#endif
IID_ISymUnmanagedBinder,
(void**)&pBinder,
NULL);
if (FAILED(hr))
{
-#ifdef FEATURE_CORECLR
RETURN (NULL);
-#else
- ThrowHR(hr);
-#endif
}
}
continue;
}
-#if defined(FEATURE_CORECLR)
// If we have been passed the binding context for the loaded assembly that is being looked up in the
// cache, then set it up in the AssemblySpec for the cache lookup to use it below.
if (pBindingContextForLoadedAssembly != NULL)
_ASSERTE(spec.GetBindingContext() == NULL);
spec.SetBindingContext(pBindingContextForLoadedAssembly);
}
-#endif // defined(FEATURE_CORECLR)
DomainAssembly * pDomainAssembly = nullptr;
#ifdef FEATURE_APPX_BINDER
szWinRtTypeClassName);
AssemblySpec spec;
spec.InitializeSpec(kAssemblyRef, GetMDImport(), GetDomainFile(GetAppDomain())->GetDomainAssembly(), IsIntrospectionOnly());
-#if defined(FEATURE_CORECLR)
// Set the binding context in the AssemblySpec if one is available. This can happen if the LoadAssembly ended up
// invoking the custom AssemblyLoadContext implementation that returned a reference to an assembly bound to a different
// AssemblyLoadContext implementation.
{
spec.SetBindingContext(pBindingContext);
}
-#endif // defined(FEATURE_CORECLR)
if (szWinRtTypeClassName != NULL)
{
spec.SetWindowsRuntimeType(szWinRtTypeNamespace, szWinRtTypeClassName);
}
}
-#ifdef FEATURE_CORECLR
#ifndef DACCESS_COMPILE
BOOL IsVerifiableWrapper(MethodDesc* pMD)
{
EEFileLoadException::Throw(GetFile(), COR_E_VERIFICATION);
#endif //DACCESS_COMPILE
}
-#endif //FEATURE_CORECLR
#if defined(_DEBUG) && !defined(DACCESS_COMPILE) && !defined(CROSS_COMPILE)
#define GUID_TO_TYPE_HASH_BUCKETS 16
// The native symbol reader dll name
-#ifdef FEATURE_CORECLR
#if defined(_AMD64_)
#define NATIVE_SYMBOL_READER_DLL W("Microsoft.DiaSymReader.Native.amd64.dll")
#elif defined(_X86_)
//#define NATIVE_SYMBOL_READER_DLL W("Microsoft.DiaSymReader.Native.arm64.dll")
#define NATIVE_SYMBOL_READER_DLL W("diasymreader.dll")
#endif
-#else
-#define NATIVE_SYMBOL_READER_DLL W("diasymreader.dll")
-#endif
typedef DPTR(PersistentInlineTrackingMap) PTR_PersistentInlineTrackingMap;
}
#endif // !DACCESS_COMPILE && FEATURE_CER
-#ifdef FEATURE_CORECLR
void VerifyAllMethods();
-#endif //FEATURE_CORECLR
CrstBase *GetLookupTableCrst()
{
#include "bbsweep.h"
-#ifndef FEATURE_CORECLR
-#include <metahost.h>
-#include "assemblyusagelogmanager.h"
-#endif
#ifdef FEATURE_COMINTEROP
#include "runtimecallablewrapper.h"
DWORD dwReason,
LPVOID lpReserved);
#endif // FEATURE_MIXEDMODE
-#ifndef FEATURE_CORECLR
-BOOL STDMETHODCALLTYPE ExecuteDLL(HINSTANCE hInst,
- DWORD dwReason,
- LPVOID lpReserved,
- BOOL fFromThunk);
-#endif // !FEATURE_CORECLR
BOOL STDMETHODCALLTYPE ExecuteEXE(HMODULE hMod);
BOOL STDMETHODCALLTYPE ExecuteEXE(__in LPWSTR pImageNameIn);
#endif // !CROSSGEN_COMPILE
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-
-// Pointer to the activated CLR interface provided by the shim.
-ICLRRuntimeInfo *g_pCLRRuntime = NULL;
-
-#endif // !FEATURE_CORECLR && !CROSSGEN_COMPILE
extern "C" IExecutionEngine* __stdcall IEE();
{
BEGIN_ENTRYPOINT_NOTHROW;
-#if defined(FEATURE_CORECLR) && defined(FEATURE_APPX) && !defined(CROSSGEN_COMPILE)
+#if defined(FEATURE_APPX) && !defined(CROSSGEN_COMPILE)
STARTUP_FLAGS startupFlags = CorHost2::GetStartupFlags();
// On CoreCLR, the host is in charge of determining whether the process is AppX or not.
AppX::SetIsAppXProcess(!!(startupFlags & STARTUP_APPX_APP_MODEL));
// A host can specify that it only wants one version of hosting interface to be used.
BOOL g_singleVersionHosting;
-#ifndef FEATURE_CORECLR
-HRESULT STDMETHODCALLTYPE
-SetRuntimeInfo(
- IUnknown * pUnk,
- STARTUP_FLAGS dwStartupFlags,
- LPCWSTR pwzHostConfig,
- const CoreClrCallbacks ** ppClrCallbacks)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- ENTRY_POINT;
- PRECONDITION(CheckPointer(pUnk));
- PRECONDITION(CheckPointer(pwzHostConfig, NULL_OK));
- } CONTRACTL_END;
-
- ICLRRuntimeInfo *pRuntime;
- HRESULT hr;
-
- IfFailGo(pUnk->QueryInterface(IID_ICLRRuntimeInfo, (LPVOID *)&pRuntime));
-
- IfFailGo(CorHost2::SetFlagsAndHostConfig(dwStartupFlags, pwzHostConfig, FALSE));
- if (InterlockedCompareExchangeT(&g_pCLRRuntime, pRuntime, NULL) != NULL)
- {
- // already set, release this one
- pRuntime->Release();
- }
- *ppClrCallbacks = &GetClrCallbacks();
-
-ErrExit:
- return hr;
-}
-#endif // !FEATURE_CORECLR
-
-#ifndef FEATURE_CORECLR
-HRESULT InitializeHostConfigFile()
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(return E_OUTOFMEMORY);
- } CONTRACTL_END;
-
- g_pszHostConfigFile = CorHost2::GetHostConfigFile();
- g_dwHostConfigFile = (g_pszHostConfigFile == NULL ? 0 : wcslen(g_pszHostConfigFile));
-
- return S_OK;
-}
-#endif // !FEATURE_CORECLR
void InitializeStartupFlags()
{
STARTUP_FLAGS flags = CorHost2::GetStartupFlags();
-#ifndef FEATURE_CORECLR
- // If we are running under a requested performance default mode, honor any changes to startup flags
- // In the future, we could make this conditional on the host telling us which subset of flags is
- // valid to override. See file:PerfDefaults.h
- flags = PerformanceDefaults::GetModifiedStartupFlags(flags);
-#endif // !FEATURE_CORECLR
if (flags & STARTUP_CONCURRENT_GC)
g_IGCconcurrent = 1;
else
g_IGCconcurrent = 0;
-#ifndef FEATURE_CORECLR // TODO: We can remove this. Retaining it now just to be safe
- if (flags & STARTUP_SINGLE_VERSION_HOSTING_INTERFACE)
- {
- g_singleVersionHosting = TRUE;
- }
-
-#ifndef FEATURE_CORECLR
- g_pConfig->SetDisableCommitThreadStack(!CLRHosted() || (flags & STARTUP_DISABLE_COMMITTHREADSTACK));
-#else
- g_pConfig->SetDisableCommitThreadStack(true);
-#endif
-
- if(flags & STARTUP_LEGACY_IMPERSONATION)
- g_pConfig->SetLegacyImpersonationPolicy();
-
- if(flags & STARTUP_ALWAYSFLOW_IMPERSONATION)
- g_pConfig->SetAlwaysFlowImpersonationPolicy();
-
- if(flags & STARTUP_HOARD_GC_VM)
- g_IGCHoardVM = 1;
- else
- g_IGCHoardVM = 0;
-
-#ifdef GCTRIMCOMMIT
- if (flags & STARTUP_TRIM_GC_COMMIT)
- g_IGCTrimCommit = 1;
- else
- g_IGCTrimCommit = 0;
-#endif
-
- if(flags & STARTUP_ETW)
- g_fEnableETW = TRUE;
-
- if(flags & STARTUP_ARM)
- g_fEnableARM = TRUE;
-#endif // !FEATURE_CORECLR
InitializeHeapType((flags & STARTUP_SERVER_GC) != 0);
}
}
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-void InitAssemblyUsageLogManager()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- g_pIAssemblyUsageLogGac = NULL;
-
- AssemblyUsageLogManager::Config config;
-
- config.wszLogDir = NULL;
- config.cLogBufferSize = 32768;
-#ifdef FEATURE_APPX
- config.uiLogRefreshInterval = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NGenAssemblyUsageLogRefreshInterval);
-#endif
-
- NewArrayHolder<WCHAR> szCustomLogDir(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NGenAssemblyUsageLog));
- config.wszLogDir = szCustomLogDir;
-
- AssemblyUsageLogManager::Init(&config);
-
- // Once the logger is initialized, create a log object for logging GAC loads.
- AssemblyUsageLogManager::GetUsageLogForContext(W("fusion"), W("GAC"), &g_pIAssemblyUsageLogGac);
-}
-#endif
// ---------------------------------------------------------------------------
// %%Function: EEStartupHelper
if (!g_pConfig)
{
IfFailGo(EEConfig::Setup());
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- IfFailGo(InitializeHostConfigFile());
- IfFailGo(g_pConfig->SetupConfiguration());
-#endif // !FEATURE_CORECLR && !CROSSGEN_COMPILE
}
#ifndef CROSSGEN_COMPILE
NumaNodeInfo::InitNumaNodeInfo();
CPUGroupInfo::EnsureInitialized();
-#ifndef FEATURE_CORECLR
- // Check in EEConfig whether a workload-specific set of performance defaults have been requested
- // This needs to be done before InitializeStartupFlags in case one is to be overridden
- PerformanceDefaults::InitializeForScenario(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerformanceScenario));
-#endif
// Initialize global configuration settings based on startup flags
// This needs to be done before the EE has started
#endif // CROSSGEN_COMPILE
-#ifndef FEATURE_CORECLR
- // Ensure initialization of Apphacks environment variables
- GetGlobalCompatibilityFlags();
-#endif // !FEATURE_CORECLR
#ifdef STRESS_LOG
if (REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_StressLog, g_pConfig->StressLog ()) != 0) {
#ifndef CROSSGEN_COMPILE
-#if defined(STRESS_HEAP) && defined(_DEBUG) && !defined(FEATURE_CORECLR)
- // TODO: is this still an issue?
- // There is a race that causes random AVs on dual proc boxes
- // that we suspect is due to memory coherancy problems (see Whidbey bug 2360)
- // Avoid the issue by making the box effectively single proc.
- if (GCStress<cfg_instr>::IsEnabled() &&
- g_SystemInfo.dwNumberOfProcessors > 1)
- SetProcessAffinityMask(GetCurrentProcess(),
- 1 << (DbgGetEXETimeStamp() % g_SystemInfo.dwNumberOfProcessors));
-#endif // STRESS_HEAP && _DEBUG && !FEATURE_CORECLR
#ifdef FEATURE_PREJIT
// Initialize the sweeper thread. THis is violating our rules with hosting
GCInterface::m_MemoryPressureLock.Init(CrstGCMemoryPressure);
-#ifndef FEATURE_CORECLR
- // Initialize Assembly Usage Logger
- InitAssemblyUsageLogManager();
-#endif
#endif // CROSSGEN_COMPILE
SystemDomain::System()->PublishAppDomainAndInformDebugger(SystemDomain::System()->DefaultDomain());
#endif
-#ifndef FEATURE_CORECLR
- ExistingOobAssemblyList::Init();
-#endif
#endif // CROSSGEN_COMPILE
}
//For a similar reason, let's not run VerifyAllOnLoad either.
-#ifdef FEATURE_CORECLR
if (g_pConfig->VerifyModulesOnLoad())
{
SystemDomain::SystemModule()->VerifyAllMethods();
}
-#endif //FEATURE_CORECLR
// Perform mscorlib consistency check if requested
g_Mscorlib.CheckExtended();
// process exit code. This can be modified by the app via System.SetExitCode().
SetLatchedExitCode(exitCode);
-#ifndef FEATURE_CORECLR // no shim
- // Bump up the ref-count on the module
- for (int i =0; i<6; i++)
- CLRLoadLibrary(MSCOREE_SHIM_W);
-#endif // FEATURE_CORECLR
ForceEEShutdown(sca);
if (pdwStartupFlags != NULL) // this parameter is optional
{
*pdwStartupFlags = 0;
-#ifndef FEATURE_CORECLR
- if (g_fEEStarted)
- {
- *pdwStartupFlags = CorHost2::GetStartupFlags();
- }
-#endif
}
return g_fEEStarted;
}
ETW::EnumerationLog::ProcessShutdown();
}
-#if defined(FEATURE_CAS_POLICY) || defined(FEATURE_COMINTEROP)
+#if defined(FEATURE_COMINTEROP)
// Get the current thread.
Thread * pThisThread = GetThread();
#endif
fFinalizeOK = FinalizerThread::FinalizerThreadWatchDog();
}
-#ifndef FEATURE_CORECLR
- if (!g_fFastExitProcess)
- {
- // Log usage data to disk. (Only do this in normal shutdown scenarios, and not involving ngen)
- if (!IsCompilationProcess())
- AssemblyUsageLogManager::GenerateLog(AssemblyUsageLogManager::GENERATE_LOG_FLAGS_NONE);
- }
-#endif
// Ok. Let's stop the EE.
if (!g_fProcessDetach)
}
#endif // PROFILING_SUPPORTED
-#ifndef FEATURE_CORECLR
- // CoEEShutDownCOM moved to
- // the Finalizer thread. See bug 87809
- if (!g_fProcessDetach && !g_fFastExitProcess)
- {
- g_fEEShutDown |= ShutDown_COM;
- if (fFinalizeOK)
- {
- FinalizerThread::FinalizerThreadWatchDog();
- }
- }
-#ifdef _DEBUG
- else
- g_fEEShutDown |= ShutDown_COM;
-#endif
-#endif //FEATURE_CORECLR
#ifdef _DEBUG
g_fEEShutDown |= ShutDown_SyncBlock;
// because we are shutting down.
CONTRACT_VIOLATION(ModeViolation);
-#ifdef FEATURE_CAS_POLICY
- // Save the security policy cache as necessary.
- if (!g_fProcessDetach || pThisThread != NULL)
- {
- // If process shutdown has started, it is not safe to create Thread object which is needed
- // by the following call.
- Security::SaveCache();
- }
-#endif
#ifdef FEATURE_COMINTEROP
// We need to call CoUninitialize in part one to ensure orderly shutdown of COM dlls.
if (!g_fFastExitProcess)
}
-#ifndef FEATURE_CORECLR
-//*****************************************************************************
-// This entry point is called from the native DllMain of the loaded image.
-// This gives the COM+ loader the chance to dispatch the loader event. The
-// first call will cause the loader to look for the entry point in the user
-// image. Subsequent calls will dispatch to either the user's DllMain or
-// their Module derived class.
-//*****************************************************************************
-BOOL STDMETHODCALLTYPE _CorDllMain( // TRUE on success, FALSE on error.
- HINSTANCE hInst, // Instance handle of the loaded module.
- DWORD dwReason, // Reason for loading.
- LPVOID lpReserved // Unused.
- )
-{
- STATIC_CONTRACT_NOTHROW;
- //STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_ENTRY_POINT;
-
- //BEGIN_ENTRYPOINT_NOTHROW;
-
- struct Param
- {
- HINSTANCE hInst;
- DWORD dwReason;
- LPVOID lpReserved;
- BOOL retval;
- } param;
- param.hInst = hInst;
- param.dwReason = dwReason;
- param.lpReserved = lpReserved;
- param.retval = FALSE;
-
- // Can't use PAL_TRY/EX_TRY here as they access the ClrDebugState which gets blown away as part of the
- // PROCESS_DETACH path. Must use special PAL_TRY_FOR_DLLMAIN, passing the reason were in the DllMain.
- PAL_TRY_FOR_DLLMAIN(Param *, pParam, ¶m, pParam->dwReason)
- {
-#ifdef _DEBUG
- if (CLRTaskHosted() &&
- ((pParam->dwReason == DLL_PROCESS_ATTACH && pParam->lpReserved == NULL) || // LoadLibrary of a managed dll
- (pParam->dwReason == DLL_PROCESS_DETACH && pParam->lpReserved == NULL) // FreeLibrary of a managed dll
- )) {
- // OS loader lock is being held by the current thread. We can not allow the fiber
- // to be rescheduled here while processing DllMain for managed dll.
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTask *pTask = GetCurrentHostTask();
- if (pTask) {
- Thread *pThread = GetThread();
- _ASSERTE (pThread);
- _ASSERTE (pThread->HasThreadAffinity());
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- }
-#endif
- // Since we're in _CorDllMain, we know that we were not called because of a
- // bootstrap thunk, since they will call CorDllMainForThunk. Because of this,
- // we can pass FALSE for the fFromThunk parameter.
- pParam->retval = ExecuteDLL(pParam->hInst,pParam->dwReason,pParam->lpReserved, FALSE);
- }
- PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- }
- PAL_ENDTRY;
-
- //END_ENTRYPOINT_NOTHROW;
-
- return param.retval;
-}
-
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_MIXEDMODE
//*****************************************************************************
#endif // FEATURE_MIXEDMODE
-#ifndef FEATURE_CORECLR
-
-// This function will do some additional PE Checks to make sure everything looks good.
-// We must do these before we run any managed code (that's why we can't do them in PEVerifier, as
-// managed code is used to determine the policy settings)
-HRESULT DoAdditionalPEChecks(HINSTANCE hInst)
-{
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_TRIGGERS;
-
- struct Param
- {
- HINSTANCE hInst;
- HRESULT hr;
- } param;
- param.hInst = hInst;
- param.hr = S_OK;
-
- PAL_TRY(Param *, pParam, ¶m)
- {
- PEDecoder pe(pParam->hInst);
-
- if (!pe.CheckWillCreateGuardPage())
- pParam->hr = COR_E_BADIMAGEFORMAT;
- }
- PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- }
- PAL_ENDTRY
-
- return param.hr;
-}
-
-//*****************************************************************************
-// This entry point is called from the native entry point of the loaded
-// executable image. This simply calls into _CorExeMainInternal, the real
-// entry point inside a filter to trigger unhandled exception processing in the
-// event an exception goes unhandled, independent of the OS UEF mechanism.
-//*****************************************************************************
-__int32 STDMETHODCALLTYPE _CorExeMain( // Executable exit code.
- )
-{
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_THROWS;
-
- // We really have nothing to share with our filter at this point.
- struct Param
- {
- PVOID pData;
- } param;
- param.pData = NULL;
-
- PAL_TRY(Param*, _pParam, ¶m)
- {
- // Call the real function that will invoke the managed entry point
- _CorExeMainInternal();
- }
- PAL_EXCEPT_FILTER(EntryPointFilter)
- {
- LOG((LF_STARTUP, LL_INFO10, "EntryPointFilter returned EXCEPTION_EXECUTE_HANDLER!"));
- }
- PAL_ENDTRY;
-
- return 0;
-}
-
-//*****************************************************************************
-// This entry point is called from _CorExeMain. If an exception goes unhandled
-// from here, we will trigger unhandled exception processing in _CorExeMain.
-//
-// The command line arguments and other entry point data
-// will be gathered here. The entry point for the user image will be found
-// and handled accordingly.
-//*****************************************************************************
-__int32 STDMETHODCALLTYPE _CorExeMainInternal( // Executable exit code.
- )
-{
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_ENTRY_POINT;
-
- // Yes, CorExeMain needs throws. If an exception passes through here, it will cause the
- // "The application has generated an unhandled exception" dialog and offer to debug.
-
- BEGIN_ENTRYPOINT_THROWS;
-
- // Make sure PE file looks ok
- HRESULT hr;
- {
- // We are early in the process, if we get an SO here we will just rip
- CONTRACT_VIOLATION(SOToleranceViolation);
- if (FAILED(hr = DoAdditionalPEChecks(WszGetModuleHandle(NULL))))
- {
- GCX_PREEMP();
- VMDumpCOMErrors(hr);
- SetLatchedExitCode (-1);
- goto exit;
- }
- }
-
- g_fEEManagedEXEStartup = TRUE;
- // Before we initialize the EE, make sure we've snooped for all EE-specific
- // command line arguments that might guide our startup.
- WCHAR *pCmdLine = WszGetCommandLine();
- HRESULT result = CorCommandLine::SetArgvW(pCmdLine);
-
- if (SUCCEEDED(result))
- {
- g_fWeOwnProcess = TRUE;
- result = EnsureEEStarted(COINITEE_MAIN);
- }
-
- if (FAILED(result))
- {
- g_fWeOwnProcess = FALSE;
- GCX_PREEMP();
- VMDumpCOMErrors(result);
- SetLatchedExitCode (-1);
- goto exit;
- }
-
- INSTALL_UNWIND_AND_CONTINUE_HANDLER;
-
- // This will be called from a EXE so this is a self referential file so I am going to call
- // ExecuteEXE which will do the work to make a EXE load.
-
- BOOL bretval = 0;
-
- bretval = ExecuteEXE(WszGetModuleHandle(NULL));
- if (!bretval) {
- // The only reason I've seen this type of error in the wild is bad
- // metadata file format versions and inadequate error handling for
- // partially signed assemblies. While this may happen during
- // development, our customers should not get here. This is a back-stop
- // to catch CLR bugs. If you see this, please try to find a better way
- // to handle your error, like throwing an unhandled exception.
- EEMessageBoxCatastrophic(IDS_EE_COREXEMAIN_FAILED_TEXT, IDS_EE_COREXEMAIN_FAILED_TITLE);
- SetLatchedExitCode (-1);
- }
-
- UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
-
-exit:
- STRESS_LOG1(LF_STARTUP, LL_ALWAYS, "Program exiting: return code = %d", GetLatchedExitCode());
-
- STRESS_LOG0(LF_STARTUP, LL_INFO10, "EEShutDown invoked from _CorExeMainInternal");
-
- EEPolicy::HandleExitProcess();
-
- END_ENTRYPOINT_THROWS;
-
- return 0;
-}
-
-
-static BOOL CacheCommandLine(__in LPWSTR pCmdLine, __in_opt LPWSTR* ArgvW)
-{
- CONTRACTL {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pCmdLine));
- PRECONDITION(CheckPointer(ArgvW));
- } CONTRACTL_END;
-
- if (pCmdLine) {
- size_t len = wcslen(pCmdLine);
-
- _ASSERT(g_pCachedCommandLine== NULL);
- g_pCachedCommandLine = new WCHAR[len+1];
- wcscpy_s(g_pCachedCommandLine, len+1, pCmdLine);
- }
-
- if (ArgvW != NULL && ArgvW[0] != NULL) {
- PathString wszModuleName;
- PathString wszCurDir;
- if (!WszGetCurrentDirectory(wszCurDir))
- return FALSE;
-
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:25025)
-#endif
-
- // usage of PathCombine is safe if we ensure that buffer specified by
- // parameter1 can accomodate buffers specified by paramater2, parameter3
- // and one path separator
- COUNT_T wszModuleName_len = wszCurDir.GetCount() + lstrlenW(ArgvW[0]);
- WCHAR* wszModuleName_buf = wszModuleName.OpenUnicodeBuffer(wszModuleName_len);
-
- if (PathCombine(wszModuleName_buf, wszCurDir, ArgvW[0]) == NULL)
- return FALSE;
- wszModuleName.CloseBuffer();
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
- size_t len = wszModuleName.GetCount();
- _ASSERT(g_pCachedModuleFileName== NULL);
- g_pCachedModuleFileName = new WCHAR[len+1];
- wcscpy_s(g_pCachedModuleFileName, len+1, wszModuleName);
- }
-
- return TRUE;
-}
-
-//*****************************************************************************
-// This entry point is called from the native entry point of the loaded
-// executable image. The command line arguments and other entry point data
-// will be gathered here. The entry point for the user image will be found
-// and handled accordingly.
-//*****************************************************************************
-__int32 STDMETHODCALLTYPE _CorExeMain2( // Executable exit code.
- PBYTE pUnmappedPE, // -> memory mapped code
- DWORD cUnmappedPE, // Size of memory mapped code
- __in LPWSTR pImageNameIn, // -> Executable Name
- __in LPWSTR pLoadersFileName, // -> Loaders Name
- __in LPWSTR pCmdLine) // -> Command Line
-{
-
- // This entry point is used by clix
- BOOL bRetVal = 0;
-
- BEGIN_ENTRYPOINT_VOIDRET;
- {
- // Before we initialize the EE, make sure we've snooped for all EE-specific
- // command line arguments that might guide our startup.
- HRESULT result = CorCommandLine::SetArgvW(pCmdLine);
-
- if (!CacheCommandLine(pCmdLine, CorCommandLine::GetArgvW(NULL))) {
- LOG((LF_STARTUP, LL_INFO10, "Program exiting - CacheCommandLine failed\n"));
- bRetVal = -1;
- goto exit;
- }
-
- if (SUCCEEDED(result))
- result = InitializeEE(COINITEE_MAIN);
-
- if (FAILED(result)) {
- VMDumpCOMErrors(result);
- SetLatchedExitCode (-1);
- goto exit;
- }
-
- // Load the executable
- bRetVal = ExecuteEXE(pImageNameIn);
-
- if (!bRetVal) {
- // The only reason I've seen this type of error in the wild is bad
- // metadata file format versions and inadequate error handling for
- // partially signed assemblies. While this may happen during
- // development, our customers should not get here. This is a back-stop
- // to catch CLR bugs. If you see this, please try to find a better way
- // to handle your error, like throwing an unhandled exception.
- EEMessageBoxCatastrophic(IDS_EE_COREXEMAIN2_FAILED_TEXT, IDS_EE_COREXEMAIN2_FAILED_TITLE);
- SetLatchedExitCode (-1);
- }
-
-exit:
- STRESS_LOG1(LF_STARTUP, LL_ALWAYS, "Program exiting: return code = %d", GetLatchedExitCode());
-
- STRESS_LOG0(LF_STARTUP, LL_INFO10, "EEShutDown invoked from _CorExeMain2");
-
- EEPolicy::HandleExitProcess();
- }
- END_ENTRYPOINT_VOIDRET;
-
- return bRetVal;
-}
-
-//*****************************************************************************
-// This is the call point to wire up an EXE. In this case we have the HMODULE
-// and just need to make sure we do to correct self referantial things.
-//*****************************************************************************
-
-
-BOOL STDMETHODCALLTYPE ExecuteEXE(HMODULE hMod)
-{
- STATIC_CONTRACT_GC_TRIGGERS;
-
- _ASSERTE(hMod);
- if (!hMod)
- return FALSE;
-
- ETWFireEvent(ExecExe_V1);
-
- struct Param
- {
- HMODULE hMod;
- } param;
- param.hMod = hMod;
-
- EX_TRY_NOCATCH(Param *, pParam, ¶m)
- {
- // Executables are part of the system domain
- SystemDomain::ExecuteMainMethod(pParam->hMod);
- }
- EX_END_NOCATCH;
-
- ETWFireEvent(ExecExeEnd_V1);
-
- return TRUE;
-}
-
-BOOL STDMETHODCALLTYPE ExecuteEXE(__in LPWSTR pImageNameIn)
-{
- STATIC_CONTRACT_GC_TRIGGERS;
-
- EX_TRY_NOCATCH(LPWSTR, pImageNameInner, pImageNameIn)
- {
- WCHAR wzPath[MAX_LONGPATH];
- DWORD dwPathLength = 0;
-
- // get the path of executable
- dwPathLength = WszGetFullPathName(pImageNameInner, MAX_LONGPATH, wzPath, NULL);
-
- if (!dwPathLength || dwPathLength > MAX_LONGPATH)
- {
- ThrowWin32( !dwPathLength ? GetLastError() : ERROR_FILENAME_EXCED_RANGE);
- }
-
- SystemDomain::ExecuteMainMethod( NULL, (WCHAR *)wzPath );
- }
- EX_END_NOCATCH;
-
- return TRUE;
-}
-#endif // FEATURE_CORECLR
#ifdef FEATURE_MIXEDMODE
return SUCCEEDED(hr);
}
-#if !defined(FEATURE_CORECLR) && defined(_DEBUG)
-//*****************************************************************************
-// Factor some common debug code.
-//*****************************************************************************
-static void EnsureManagedThreadExistsForHostedThread()
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- if (CLRTaskHosted()) {
- // If CLR is hosted, and this is on a thread that a host controls,
- // we must have created Thread object.
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTask *pHostTask = GetCurrentHostTask();
- if (pHostTask)
- {
- CONSISTENCY_CHECK(CheckPointer(GetThread()));
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- }
-}
-#endif // !FEATURE_CORECLR && _DEBUG
#ifdef FEATURE_MIXEDMODE
//*****************************************************************************
#endif // FEATURE_MIXEDMODE
-#ifndef FEATURE_CORECLR
-//*****************************************************************************
-// This is the call point to make a DLL that is already loaded into our address
-// space run. There will be other code to actually have us load a DLL due to a
-// class reference.
-//*****************************************************************************
-BOOL STDMETHODCALLTYPE ExecuteDLL(HINSTANCE hInst,
- DWORD dwReason,
- LPVOID lpReserved,
- BOOL fFromThunk)
-{
-
- CONTRACTL{
- THROWS;
- WRAPPER(GC_TRIGGERS);
- MODE_ANY;
- ENTRY_POINT;
- PRECONDITION(CheckPointer(lpReserved, NULL_OK));
- PRECONDITION(CheckPointer(hInst));
- PRECONDITION(GetThread() != NULL || !fFromThunk);
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BOOL fRetValue = FALSE;
-
- // This needs to be before the BEGIN_ENTRYPOINT_THROWS since
- // we can't call ReportStackOverflow if we're almost done with
- // shutdown and can't run managed code.
- if (!CanRunManagedCode(LoaderLockCheck::None))
- {
- return fRetValue;
- }
-
- BEGIN_ENTRYPOINT_THROWS;
-
- Thread *pThread = GetThread();
-
- if (!hInst)
- {
- fRetValue = ExecuteDLL_ReturnOrThrow(E_FAIL, fFromThunk);
- goto Exit;
- }
-
- // Note that we always check fFromThunk before checking the dwReason value.
- // This is because the dwReason value is undefined in the case that we're
- // being invoked due to a bootstrap (because that is by definition outside
- // of the loader lock and there is no appropriate dwReason value).
- if (fFromThunk ||
- dwReason == DLL_PROCESS_ATTACH ||
- dwReason == DLL_THREAD_ATTACH)
- {
- INDEBUG(EnsureManagedThreadExistsForHostedThread();)
-
-
- // If necessary, start the runtime and create a managed thread object.
- if (fFromThunk || dwReason == DLL_PROCESS_ATTACH)
- {
- hr = EnsureEEStarted(COINITEE_DLL);
-
- if (SUCCEEDED(hr) && pThread == NULL)
- {
- pThread = SetupThreadNoThrow(&hr);
- }
-
- if(FAILED(hr))
- {
- fRetValue = ExecuteDLL_ReturnOrThrow(hr, fFromThunk);
- goto Exit;
- }
- }
-
- // IJW assemblies cause the thread doing the process attach to
- // re-enter ExecuteDLL and do a thread attach. This happens when
- // CoInitializeEE() above executed
- else if (!(pThread &&
- pThread->GetDomain() &&
- CanRunManagedCode(LoaderLockCheck::None)))
- {
- fRetValue = ExecuteDLL_ReturnOrThrow(S_OK, fFromThunk);
- goto Exit;
- }
-
- // we now have a thread setup - either the 1st if set it up, or
- // the else if ran if we didn't have a thread setup.
-
-#ifdef FEATURE_MIXEDMODE
-
- EX_TRY
- {
- hr = ExecuteDLLForAttach(hInst, dwReason, lpReserved, fFromThunk);
- }
- EX_CATCH
- {
- // We rethrow directly here instead of using ExecuteDLL_ReturnOrThrow() to
- // preserve the full exception information, rather than just the HRESULT
- if (fFromThunk)
- {
- EX_RETHROW;
- }
- else
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- if (FAILED(hr))
- {
- fRetValue = ExecuteDLL_ReturnOrThrow(hr, fFromThunk);
- goto Exit;
- }
-#endif // FEATURE_MIXEDMODE
- }
- else
- {
- PEDecoder pe(hInst);
- if (pe.HasManagedEntryPoint())
- {
- // If the EE is still intact, then run user entry points. Otherwise
- // detach was handled when the app domain was stopped.
- //
- // Checks for the loader lock will occur within RunDllMain, if that's
- FAULT_NOT_FATAL();
- if (CanRunManagedCode(LoaderLockCheck::None))
- {
- hr = SystemDomain::RunDllMain(hInst, dwReason, lpReserved);
- }
- }
- // This does need to match the attach. We will only unload dll's
- // at the end and CoUninitialize will just bounce at 0. WHEN and IF we
- // get around to unloading IL DLL's during execution prior to
- // shutdown we will need to bump the reference one to compensate
- // for this call.
- if (dwReason == DLL_PROCESS_DETACH && !g_fForbidEnterEE)
- {
-#ifdef FEATURE_MIXEDMODE
- // If we're in a decent state, we need to free the memory associated
- // with the IJW thunk fixups.
- // we are not in a decent state if the process is terminating (lpReserved!=NULL)
- if (g_fEEStarted && !g_fEEShutDown && !lpReserved)
- {
- PEImage::UnloadIJWModule(hInst);
- }
-#endif // FEATURE_MIXEDMODE
- }
- }
-
- fRetValue = ExecuteDLL_ReturnOrThrow(hr, fFromThunk);
-
-Exit:
-
- END_ENTRYPOINT_THROWS;
- return fRetValue;
-}
-#endif // !FEATURE_CORECLR
Volatile<BOOL> g_bIsGarbageCollectorFullyInitialized = FALSE;
// Remember module instance
g_pMSCorEE = pParam->hInst;
-#ifndef FEATURE_CORECLR
- CoreClrCallbacks cccallbacks;
- cccallbacks.m_hmodCoreCLR = (HINSTANCE)g_pMSCorEE;
- cccallbacks.m_pfnIEE = IEE;
- cccallbacks.m_pfnGetCORSystemDirectory = GetCORSystemDirectoryInternaL;
- cccallbacks.m_pfnGetCLRFunction = GetCLRFunction;
-
- InitUtilcode(cccallbacks);
-#endif // !FEATURE_CORECLR
// Set callbacks so that LoadStringRC knows which language our
// threads are in so that it can return the proper localized string.
hr = g_pDebugInterface->Startup(); // throw on error
_ASSERTE(SUCCEEDED(hr));
-#ifdef FEATURE_CORECLR
//
// If the debug pack is not installed, Startup will return S_FALSE
// and we should cleanup and proceed without debugging support.
{
return;
}
-#endif // FEATURE_CORECLR
- }
-
-#if !defined(FEATURE_CORECLR) // simple hosting
- // If there's a DebuggerThreadControl interface, then we
- // need to update the DebuggerSpecialThread list.
- if (CorHost::GetDebuggerThreadControl())
- {
- hr = CorHost::RefreshDebuggerSpecialThreadList();
- _ASSERTE((SUCCEEDED(hr)) && (hr != S_FALSE));
-
- // So we don't think this will ever fail, but just in case...
- IfFailThrow(hr);
}
- // If there is a DebuggerThreadControl interface, then it was set before the debugger
- // was initialized and we need to provide this interface now. If debugging is already
- // initialized then the IDTC pointer is passed in when it is set through CorHost
- IDebuggerThreadControl *pDTC = CorHost::GetDebuggerThreadControl();
-
- if (pDTC != NULL)
- {
- g_pDebugInterface->SetIDbgThreadControl(pDTC);
- }
-#endif // !defined(FEATURE_CORECLR)
LOG((LF_CORDB, LL_INFO10, "Left-side debugging services setup.\n"));
g_CORDebuggerControlFlags = DBCF_NORMAL_OPERATION;
-#if !defined(FEATURE_CORECLR) // simple hosting
- CorHost::CleanupDebuggerThreadControl();
-#endif // !defined(FEATURE_CORECLR)
}
#endif // ENABLE_CONTRACTS_IMPL
-#ifndef FEATURE_CORECLR
-//-------------------------------------------------------------------------
-// CorCommandLine state and methods
-//-------------------------------------------------------------------------
-// Class to encapsulate Cor Command line processing
-
-// Statics for the CorCommandLine class
-DWORD CorCommandLine::m_NumArgs = 0;
-LPWSTR *CorCommandLine::m_ArgvW = 0;
-
-LPWSTR CorCommandLine::m_pwszAppFullName = NULL;
-DWORD CorCommandLine::m_dwManifestPaths = 0;
-LPWSTR *CorCommandLine::m_ppwszManifestPaths = NULL;
-DWORD CorCommandLine::m_dwActivationData = 0;
-LPWSTR *CorCommandLine::m_ppwszActivationData = NULL;
-
-#ifdef _DEBUG
-LPCWSTR g_CommandLine;
-#endif
-
-// Set argvw from command line
-/* static */
-HRESULT CorCommandLine::SetArgvW(LPCWSTR lpCommandLine)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- INJECT_FAULT(return E_OUTOFMEMORY;);
-
- PRECONDITION(CheckPointer(lpCommandLine));
- }
- CONTRACTL_END
-
- HRESULT hr = S_OK;
- if(!m_ArgvW) {
- INDEBUG(g_CommandLine = lpCommandLine);
-
- InitializeLogging(); // This is so early, we may not be initialized
- LOG((LF_ALWAYS, LL_INFO10, "Executing program with command line '%S'\n", lpCommandLine));
-
- m_ArgvW = SegmentCommandLine(lpCommandLine, &m_NumArgs);
-
- if (!m_ArgvW)
- return E_OUTOFMEMORY;
-
- // Click once specific parsing
- hr = ReadClickOnceEnvVariables();
- }
-
- return hr;
-}
-
-// Retrieve the command line
-/* static */
-LPWSTR* CorCommandLine::GetArgvW(DWORD *pNumArgs)
-{
- LIMITED_METHOD_CONTRACT;
-
- if (pNumArgs != 0)
- *pNumArgs = m_NumArgs;
-
- return m_ArgvW;
-}
-
-HRESULT CorCommandLine::ReadClickOnceEnvVariables()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
-
- EX_TRY
- {
- // Find out if this is a ClickOnce application being activated.
- PathString m_pwszAppFullNameHolder;
- DWORD cAppFullName = WszGetEnvironmentVariable(g_pwzClickOnceEnv_FullName, m_pwszAppFullNameHolder);
- if (cAppFullName > 0) {
- // get the application full name.
- m_pwszAppFullName = m_pwszAppFullNameHolder.GetCopyOfUnicodeString();
-
- // reset the variable now that we read it so child processes
- // do not think they are a clickonce app.
- WszSetEnvironmentVariable(g_pwzClickOnceEnv_FullName, NULL);
-
- // see if we have application manifest files.
- DWORD dwManifestPaths = 0;
- while (1) {
- StackSString manifestFile(g_pwzClickOnceEnv_Manifest);
- StackSString buf;
- COUNT_T size = buf.GetUnicodeAllocation();
- _itow_s(dwManifestPaths, buf.OpenUnicodeBuffer(size), size, 10);
- buf.CloseBuffer();
- manifestFile.Append(buf);
- SString temp;
- if (WszGetEnvironmentVariable(manifestFile.GetUnicode(), temp) > 0)
- dwManifestPaths++;
- else
- break;
- }
- m_ppwszManifestPaths = new LPWSTR[dwManifestPaths];
- for (DWORD i=0; i<dwManifestPaths; i++) {
- StackSString manifestFile(g_pwzClickOnceEnv_Manifest);
- StackSString buf;
- COUNT_T size = buf.GetUnicodeAllocation();
- _itow_s(i, buf.OpenUnicodeBuffer(size), size, 10);
- buf.CloseBuffer();
- manifestFile.Append(buf);
- PathString m_ppwszManifestPathsHolder;
- DWORD cManifestPath = WszGetEnvironmentVariable(manifestFile.GetUnicode(), m_ppwszManifestPathsHolder);
- if (cManifestPath > 0) {
-
- m_ppwszManifestPaths[i] = m_ppwszManifestPathsHolder.GetCopyOfUnicodeString();
- WszSetEnvironmentVariable(manifestFile.GetUnicode(), NULL); // reset the env. variable.
- }
- }
- m_dwManifestPaths = dwManifestPaths;
-
- // see if we have activation data arguments.
- DWORD dwActivationData = 0;
- while (1) {
- StackSString activationData(g_pwzClickOnceEnv_Parameter);
- StackSString buf;
- COUNT_T size = buf.GetUnicodeAllocation();
- _itow_s(dwActivationData, buf.OpenUnicodeBuffer(size), size, 10);
- buf.CloseBuffer();
- activationData.Append(buf);
- SString temp;
- if (WszGetEnvironmentVariable(activationData.GetUnicode(), temp) > 0)
- dwActivationData++;
- else
- break;
- }
- m_ppwszActivationData = new LPWSTR[dwActivationData];
- for (DWORD i=0; i<dwActivationData; i++) {
- StackSString activationData(g_pwzClickOnceEnv_Parameter);
- StackSString buf;
- COUNT_T size = buf.GetUnicodeAllocation();
- _itow_s(i, buf.OpenUnicodeBuffer(size), size, 10);
- buf.CloseBuffer();
- activationData.Append(buf);
- PathString m_ppwszActivationDataHolder;
- DWORD cActivationData = WszGetEnvironmentVariable(activationData.GetUnicode(), m_ppwszActivationDataHolder);
- if (cActivationData > 0) {
- m_ppwszActivationData[i] = m_ppwszActivationDataHolder.GetCopyOfUnicodeString();
- WszSetEnvironmentVariable(activationData.GetUnicode(), NULL); // reset the env. variable.
- }
- }
- m_dwActivationData = dwActivationData;
- }
- }
- EX_CATCH_HRESULT(hr);
-
- END_SO_INTOLERANT_CODE;
-
- return hr;
-}
-
-#endif // !FEATURE_CORECLR
#endif // CROSSGEN_COMPILE
//
BOOL GetOSVersion(LPOSVERSIONINFO lposVer)
{
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
-
- //declared static to cache the version info
- static OSVERSIONINFOEX osvi = {0};
- BOOL ret = TRUE;
-
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), return FALSE);
-
- //If not yet cached get the OS version info
- if(osvi.dwMajorVersion == 0)
- {
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
-
- ReleaseHolder<ICLRRuntimeHostInternal> pRuntimeHostInternal;
- //Get the interface
- HRESULT hr = g_pCLRRuntime->GetInterface(CLSID_CLRRuntimeHostInternal,
- IID_ICLRRuntimeHostInternal,
- &pRuntimeHostInternal);
-
- _ASSERT(SUCCEEDED(hr));
-
- //Call mscoree!GetVersionExWrapper() through mscoreei interface method
- hr = pRuntimeHostInternal->GetTrueOSVersion((LPOSVERSIONINFO)&osvi);
- if(!SUCCEEDED(hr))
- {
- osvi.dwMajorVersion = 0;
- ret = FALSE;
- goto FUNCEND;
- }
- }
-
- if(lposVer->dwOSVersionInfoSize==sizeof(OSVERSIONINFOEX)||lposVer->dwOSVersionInfoSize==sizeof(OSVERSIONINFO))
- {
- //Copy the cached version info to the return memory location
- memcpy(lposVer,&osvi, lposVer->dwOSVersionInfoSize);
- }
- else
- {
- //return failure if dwOSVersionInfoSize not set properly
- ret = FALSE;
- }
-
-FUNCEND:
- END_SO_INTOLERANT_CODE;
-
- return ret;
-#else
// Fix for warnings when building against WinBlue build 9444.0.130614-1739
// warning C4996: 'GetVersionExW': was declared deprecated
// externalapis\windows\winblue\sdk\inc\sysinfoapi.h(442)
#pragma warning( disable : 4996 )
return WszGetVersionEx(lposVer);
#pragma warning( default : 4996 )
-#endif
}
// Stronger than IsGCHeapInitialized
BOOL IsGarbageCollectorFullyInitialized();
-#ifndef FEATURE_CORECLR
-//---------------------------------------------------------------------------------------
-//
-// Class to encapsulate Cor Command line processing
-//
-class CorCommandLine
-{
-public:
-
-//********** TYPES
-
- // Note: We don't bother with interlocked operations as we manipulate these bits,
- // because we don't anticipate free-threaded access. (Most of this is used only
- // during startup / shutdown).
-
-//********** DATA
-
- // Hold the current (possibly parsed) command line here
- static DWORD m_NumArgs;
- static LPWSTR *m_ArgvW;
-
- static LPWSTR m_pwszAppFullName;
- static DWORD m_dwManifestPaths;
- static LPWSTR *m_ppwszManifestPaths;
- static DWORD m_dwActivationData;
- static LPWSTR *m_ppwszActivationData;
-
-//********** METHODS
-
- // parse the command line
- static HRESULT SetArgvW(LPCWSTR lpCommandLine);
-
- // Retrieve the parsed command line
- static LPWSTR *GetArgvW(DWORD *pNumArgs);
-
-private:
- static HRESULT ReadClickOnceEnvVariables();
-};
-#endif // !FEATURE_CORECLR
#endif
_ASSERTE(HasCriticalTransparentInfo());
return (m_VMFlags & VMFLAG_TRANSPARENCY_MASK) == VMFLAG_TRANSPARENCY_ALLCRITICAL_TAS ||
(m_VMFlags & VMFLAG_TRANSPARENCY_MASK) == VMFLAG_TRANSPARENCY_TAS_NOTCRITICAL
-#ifndef FEATURE_CORECLR
- || (m_VMFlags & VMFLAG_TRANSPARENCY_MASK) == VMFLAG_TRANSPARENCY_CRITICAL_TAS
-#endif // !FEATURE_CORECLR;
;
}
}
void SetCriticalTransparentInfo(
-#ifndef FEATURE_CORECLR
- BOOL fIsCritical,
-#endif // !FEATURE_CORECLR
BOOL fIsTreatAsSafe,
BOOL fIsAllTransparent,
BOOL fIsAllCritical)
// TAS wihtout critical doesn't make sense - although it was allowed in the v2 desktop model,
// so we need to allow it for compatibility reasons on the desktop.
-#ifdef FEATURE_CORECLR
_ASSERTE(!fIsTreatAsSafe || fIsAllCritical);
-#endif // FEATURE_CORECLR
//if nothing is set, then we're transparent.
unsigned flags = VMFLAG_TRANSPARENCY_TRANSPARENT;
flags = fIsTreatAsSafe ? VMFLAG_TRANSPARENCY_ALLCRITICAL_TAS :
VMFLAG_TRANSPARENCY_ALLCRITICAL;
}
-#ifndef FEATURE_CORECLR
- else if (fIsCritical)
- {
- flags = fIsTreatAsSafe ? VMFLAG_TRANSPARENCY_CRITICAL_TAS :
- VMFLAG_TRANSPARENCY_CRITICAL;
- }
-#endif // !FEATURE_CORECLR
else
{
flags = fIsTreatAsSafe ? VMFLAG_TRANSPARENCY_TAS_NOTCRITICAL :
#define g_SecurityCriticalAttribute "System.Security.SecurityCriticalAttribute"
#define g_SecurityTransparentAttribute "System.Security.SecurityTransparentAttribute"
-#ifndef FEATURE_CORECLR
-#define g_SecurityTreatAsSafeAttribute "System.Security.SecurityTreatAsSafeAttribute"
-#define g_SecurityRulesAttribute "System.Security.SecurityRulesAttribute"
-#endif //FEATURE_CORECLR
#define g_SecuritySafeCriticalAttribute "System.Security.SecuritySafeCriticalAttribute"
#include "common.h" // precompiled header
-#ifndef FEATURE_CORECLR
-#include "assemblyusagelogmanager.h"
-#endif
#include "clr/fs/file.h"
#include "clrprivbinderwinrt.h"
#include "clrprivbinderutil.h"
#endif
#include <TypeResolution.h>
#include "delayloadhelpers.h"
-#ifdef FEATURE_CORECLR
#include "../binder/inc/applicationcontext.hpp"
#include "../binder/inc/assemblybinder.hpp"
#include "../binder/inc/assembly.hpp"
#include "../binder/inc/debuglog.hpp"
#include "../binder/inc/utils.hpp"
#include "../binder/inc/fusionassemblyname.hpp"
-#endif
#ifdef CROSSGEN_COMPILE
#include "crossgenroresolvenamespace.h"
, m_fCanUseNativeImages(fCanUseNativeImages)
#endif
, m_fNamespaceResolutionKind(fNamespaceResolutionKind)
-#ifdef FEATURE_CORECLR
, m_pApplicationContext(nullptr)
, m_appLocalWinMDPath(nullptr)
-#endif
#ifdef FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
, m_fCanSetLocalWinMDPath(TRUE)
#endif // FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
m_rgAltPaths.GetRawArray() + iAltPath));
}
}
-#if defined(FEATURE_APPX) && !defined(FEATURE_CORECLR)
- else if (AppX::IsAppXNGen())
- {
- // If this is an NGen worker process for AppX, then the process doesn't actually run in the package,
- // and RoResolveNamespace won't work without some help. AppX::GetCurrentPackageInfo can give us the
- // package graph, which we can pass to RoResolveNamespace to make it work properly.
- UINT32 cbBuffer = 0;
- UINT32 nCount = 0;
- HRESULT hr = AppX::GetCurrentPackageInfo(PACKAGE_FILTER_CLR_DEFAULT, &cbBuffer, nullptr, nullptr);
- if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- ThrowHR(hr);
-
- NewArrayHolder<BYTE> pbBuffer(new (nothrow) BYTE[cbBuffer]);
- IfNullThrow(pbBuffer);
- IfFailThrow(AppX::GetCurrentPackageInfo(PACKAGE_FILTER_CLR_DEFAULT, &cbBuffer, pbBuffer, &nCount));
-
- m_rgAltPaths.Allocate(nCount);
-
- PCPACKAGE_INFO pPackageInfo = reinterpret_cast<PCPACKAGE_INFO>(static_cast<PBYTE>(pbBuffer));
- for (UINT32 iAltPath = 0; iAltPath < nCount; iAltPath++)
- {
- IfFailThrow(WindowsCreateString(
- pPackageInfo[iAltPath].path,
- (UINT32)wcslen(pPackageInfo[iAltPath].path),
- m_rgAltPaths.GetRawArray() + iAltPath));
- }
- }
-#endif //FEATURE_APPX && !FEATURE_CORECLR
#endif //CROSSGEN_COMPILE
#ifdef FEATURE_FUSION
{
WRAPPER_NO_CONTRACT;
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- AssemblyUsageLogManager::UnRegisterBinderFromUsageLog((UINT_PTR)this);
-#endif
if (m_pTypeCache != nullptr)
{
m_pTypeCache->Release();
{
pBinder.SuppressRelease();
}
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- // Create and register WinRT usage log
- ReleaseHolder<IAssemblyUsageLog> pNewWinRTUsageLog;
- IfFailThrow(AssemblyUsageLogManager::GetUsageLogForContext(W("WinRT"), W("NotApp"), &pNewWinRTUsageLog));
-
- UINT_PTR winRTBinderId;
- IfFailThrow(pBinder->GetBinderID(&winRTBinderId));
- IfFailThrow(AssemblyUsageLogManager::RegisterBinderWithUsageLog(winRTBinderId, pNewWinRTUsageLog));
-#endif
}
_ASSERTE(s_pSingleton->m_fNamespaceResolutionKind == fNamespaceResolutionKind);
HRESULT hr = S_OK;
ReleaseHolder<CLRPrivAssemblyWinRT> pAssembly;
LPWSTR wszFullTypeName = nullptr;
-#ifndef FEATURE_CORECLR
- NewArrayHolder<WCHAR> wszAssemblySimpleName;
-#endif
#ifndef CROSSGEN_COMPILE
-#ifndef FEATURE_CORECLR
- fusion::logging::StatusScope logStatus(0, ID_FUSLOG_BINDING_STATUS_WINRT, &hr);
-#else
BINDER_SPACE::BINDER_LOG_ENTER(W("CLRPrivBinderWinRT_CoreCLR::BindWinRTAssemblyByName"));
#endif
-#endif
VALIDATE_ARG_RET(pAssemblyName != nullptr);
VALIDATE_ARG_RET(ppAssembly != nullptr);
IfFailGo(COR_E_PLATFORMNOTSUPPORTED);
}
-#ifndef FEATURE_CORECLR
- IfFailGo(fusion::util::GetProperty(pAssemblyName, ASM_NAME_NAME, &wszAssemblySimpleName));
-#else
WCHAR wszAssemblySimpleName[_MAX_PATH];
{
DWORD cchAssemblySimpleName = _MAX_PATH;
IfFailGo(pAssemblyName->GetName(&cchAssemblySimpleName, wszAssemblySimpleName));
}
-#endif
wszFullTypeName = wcschr(wszAssemblySimpleName, W('!'));
pNewAssembly.SuppressRelease();
}
-#ifndef FEATURE_CORECLR
- if (fPreBind)
- {
- // We are pre-binding to this WinMD and do not want to open it
- // Compare the filename to the assembly simple name. This is legal to do with WinRT because at NGen time
- // we embed a WinRT dependency as assembly def name component plus a namespace and type from it.
- // At bind time, this type should still exist in the same assembly. If it doesn't, and has been moved,
- // the native image validation will fail anyway and we'll fall back to IL. This is because if the type has
- // been moved to another WinMD, it must have been removed from the first one because WinRT allows no duplicates.
- // See comment on CLRPrivBinderWinRT::PreBind for further details.
- if (!_wcsicmp(wszAssemblySimpleName, wszFileNameStripped))
- {
- *ppAssembly = pAssembly.Extract();
- return (hr = S_OK);
- }
- else
- {
- continue;
- }
- }
-#endif
- }
-#ifndef FEATURE_CORECLR
- else if (fPreBind)
- {
- // We are pre-binding to this WinMD and do not want to force it to be loaded into the runtime yet.
- // Compare the filename to the assembly simple name. This is legal to do with WinRT because at NGen time
- // we embed a WinRT dependency as assembly def name component plus a namespace and type from it.
- // At bind time, this type should still exist in the same assembly. If it doesn't, and has been moved,
- // the native image validation will fail anyway and we'll fall back to IL. This is because if the type has
- // been moved to another WinMD, it must have been removed from the first one because WinRT allows no duplicates.
- // See comment on CLRPrivBinderWinRT::PreBind for further details.
- if (!_wcsicmp(wszAssemblySimpleName, wszFileNameStripped))
- {
- *ppAssembly = pAssembly.Extract();
- return (hr = S_OK);
- }
- else
- {
- continue;
- }
}
-#endif
//
// Look to see if there's a native image available.
if (hr == S_OK)
{ // The type we are looking for has been found in this assembly
#ifndef CROSSGEN_COMPILE
-#ifndef FEATURE_CORECLR
- fusion::logging::LogMessage(0, ID_FUSLOG_BINDING_STATUS_FOUND, wszFileName);
-#else
BINDER_SPACE::BINDER_LOG_LEAVE_HR(W("CLRPrivBinderWinRT_CoreCLR::BindWinRTAssemblyByName"), hr);
#endif
-#endif
*ppAssembly = pAssembly.Extract();
return (hr = S_OK);
}
hr = CLR_E_BIND_TYPE_NOT_FOUND;
ErrExit:
-#ifdef FEATURE_CORECLR
BINDER_SPACE::BINDER_LOG_LEAVE_HR(W("CLRPrivBinderWinRT_CoreCLR::BindWinRTAssemblyByName"), hr);
-#endif
return hr;
} // CLRPrivBinderWinRT::BindWinRTAssemblyByName
{
HRESULT hr = S_OK;
-#ifdef FEATURE_CORECLR
if (!m_pApplicationContext->IsTpaListProvided())
return COR_E_FILENOTFOUND;
FALSE, /* fIsInGAC */
FALSE /* fExplicitBindToNativeImage */,
ppAssembly);
-#else
- ReleaseHolder<BINDER_SPACE::Assembly> pAssembly;
-
- // This codepath is used for desktop crossgen
- pAssembly = new BINDER_SPACE::Assembly();
-
- pAssembly->SetPEImage(PEImage::OpenImage(sWinmdFilename, MDInternalImport_Default));
-
- pAssembly->m_assemblyPath.Set(sWinmdFilename);
-
- *ppAssembly = pAssembly.Extract();
-#endif
return hr;
}
#endif // !FEATURE_FUSION
-#ifdef FEATURE_CORECLR
//=====================================================================================================================
HRESULT CLRPrivBinderWinRT::SetApplicationContext(BINDER_SPACE::ApplicationContext *pApplicationContext, SString &appLocalWinMD)
{
return hr;
}
-#endif //FEATURE_CORECLR
//=====================================================================================================================
// Implements interface method code:ICLRPrivBinder::BindAssemblyByName.
LPWSTR wszWinMDPath = nullptr;
UINT32 cchWinMDPath = 0;
-#ifdef FEATURE_CORECLR
wszWinMDPath = m_appLocalWinMDPath;
-#else
- if (AppX::IsAdaptiveApp())
- {
- IfFailRet(AppX::GetWinMetadataDirForAdaptiveApps(&wszWinMDPath));
- }
-
- else if (AppX::IsAppXDesignMode() || IsNgenOffline())
- {
- wszWinMDPathConfig = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_WinMDPath);
- wszWinMDPath = wszWinMDPathConfig;
- }
-#endif // FEATURE_CORECLR
if (wszWinMDPath != nullptr)
{
&rgFileNames,
nullptr, // pcDirectNamespaceChildren
nullptr); // rgDirectNamespaceChildren
-#ifdef FEATURE_CORECLR
// For CoreCLR, if the process is not AppX, deliver more appropriate error message
// when trying to bind to 3rd party WinMDs that is not confusing.
if (HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE) == hr)
IfFailRet(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));
}
}
-#endif
#ifdef FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
// If we failed to find the requested name, but we have an application local probing path setup, then
&cchFileName);
BOOL fSkipFilename = FALSE;
-#ifndef FEATURE_CORECLR
- // If we have a specified path list. Be certain to only find filenames in that list.
- // NGen for AppX is an exception, where the path list contains the package graph, and we can
- // accept files found elsewhere (e.g., in the Windows WinMD directory).
- // On CoreCLR, we have no concept of an AppX package, so we want the passed in app
- // paths to additively contribute to the set of WinMDs the API can find.
- if (m_rgAltPaths.GetCount() > 0 && !AppX::IsAppXNGen())
- {
- fSkipFilename = TRUE;
- for (DWORD iAltPath = 0; iAltPath < m_rgAltPaths.GetCount(); iAltPath++)
- {
- UINT32 cchAltPath = 0;
- LPCWSTR wszAltPath = WindowsGetStringRawBuffer(
- m_rgAltPaths.GetAt(iAltPath),
- &cchAltPath);
-
- if (cchAltPath >= cchFileName)
- continue;
-
- if (wcsncmp(wszAltPath, wszFileName, cchAltPath) == 0)
- {
- fSkipFilename = FALSE;
- break;
- }
- }
- }
-#endif
if (!fSkipFilename)
hFileNameList.InsertTail(wszFileName);
}
return S_OK;
}
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
//=====================================================================================================================
HRESULT CLRPrivBinderWinRT::FindWinRTAssemblyBySpec(
LPVOID pvAppDomain,
STATIC_CONTRACT_WRAPPER;
return E_FAIL;
}
-#endif
#ifdef FEATURE_FUSION
//=====================================================================================================================
// Forward declarations
class CLRPrivBinderWinRT;
class CLRPrivAssemblyWinRT;
-#ifdef FEATURE_CORECLR
class BINDER_SPACE::ApplicationContext;
class BINDER_SPACE::Assembly;
-#endif
typedef DPTR(CLRPrivBinderWinRT) PTR_CLRPrivBinderWinRT;
typedef DPTR(CLRPrivAssemblyWinRT) PTR_CLRPrivAssemblyWinRT;
#ifndef FEATURE_FUSION
HRESULT GetAssemblyAndTryFindNativeImage(SString &sWinmdFilename, LPCWSTR pwzSimpleName, BINDER_SPACE::Assembly ** ppAssembly);
#endif
-#ifdef FEATURE_CORECLR
// On Phone the application's APP_PATH CoreCLR hosting config property is used as the app
// package graph for RoResolveNamespace to find 3rd party WinMDs. This method wires up
// the app paths so the WinRT binder will find 3rd party WinMDs.
HRESULT SetApplicationContext(BINDER_SPACE::ApplicationContext *pApplicationContext, SString &appLocalWinMD);
-#endif
// Finds assembly with WinRT type if it is already loaded
// Note: This method could implement interface code:ICLRPrivWinRtTypeBinder if it is ever needed
PTR_Assembly FindAssemblyForTypeIfLoaded(
HRESULT GetParentIBindContext(IBindContext **ppIBindContext);
#endif //FEATURE_FUSION
-#ifdef FEATURE_CORECLR
BINDER_SPACE::ApplicationContext * m_pApplicationContext;
NewArrayHolder<WCHAR> m_appLocalWinMDPath;
-#endif
#ifdef FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
// App-local location that can be probed for WinMD files
// However, this used to be allowed in 1.0/1.1, and some third-party DLLs have
// been obfuscated so that they have duplicate private typedefs.
// We must allow this for old assemblies for app compat reasons
-#ifdef FEATURE_CORECLR
pModule->GetAssembly()->ThrowBadImageException(pszNameSpace, pszName, BFA_MULT_TYPE_SAME_NAME);
-#else
- LPCSTR pszVersion = NULL;
- if (FAILED(pModule->GetMDImport()->GetVersionString(&pszVersion)))
- {
- pModule->GetAssembly()->ThrowBadImageException(pszNameSpace, pszName, BFA_MULT_TYPE_SAME_NAME);
- }
-
- SString ssVersion(SString::Utf8, pszVersion);
- SString ssV1(SString::Literal, "v1.");
-
- AdjustImageRuntimeVersion(&ssVersion);
-
- // If not "v1.*", throw an exception
- if (!ssVersion.BeginsWith(ssV1))
- pModule->GetAssembly()->ThrowBadImageException(pszNameSpace, pszName, BFA_MULT_TYPE_SAME_NAME);
-#endif
}
}
else {
}
-#ifndef FEATURE_CORECLR
-
-//******************************************************************************
-// This function determines whether a Type is accessible from
-// outside of the assembly it lives in.
-
-static BOOL IsTypeVisibleOutsideAssembly(MethodTable* pMT)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
- DWORD dwProtection;
- // check all types in nesting chain, while inner types are public
- while (IsTdPublic(dwProtection = pMT->GetClass()->GetProtection()) ||
- IsTdNestedPublic(dwProtection))
- {
- // if type is nested, check outer type, too
- if (IsTdNested(dwProtection))
- {
- pMT = GetEnclosingMethodTable(pMT);
- }
- // otherwise, type is visible outside of the assembly
- else
- {
- return TRUE;
- }
- }
- return FALSE;
-} // static BOOL IsTypeVisibleOutsideAssembly(MethodTable* pMT)
-
-#endif //!FEATURE_CORECLR
//******************************************************************************
BOOL canAccessTarget = FALSE;
#ifndef CROSSGEN_COMPILE
-#ifdef FEATURE_CORECLR
BOOL fAccessingFrameworkCode = FALSE;
ThrowAccessException(pContext, pTargetMT, NULL, fAccessingFrameworkCode);
}
-#else // FEATURE_CORECLR
-
- GCX_COOP();
-
- // Overriding the rules of visibility checks in Win8 immersive: no access is allowed to internal
- // code in the framework even in full trust, unless the caller is also framework code.
- if ( (m_accessCheckType == kUserCodeOnlyRestrictedMemberAccess ||
- m_accessCheckType == kUserCodeOnlyRestrictedMemberAccessNoTransparency) &&
- visibilityCheck )
- {
- IAssemblyName *pIAssemblyName = pTargetMT->GetAssembly()->GetFusionAssemblyName();
-
- HRESULT hr = Fusion::Util::IsAnyFrameworkAssembly(pIAssemblyName);
-
- // S_OK: pIAssemblyName is a framework assembly.
- // S_FALSE: pIAssemblyName is not a framework assembly.
- // Other values: pIAssemblyName is an invalid name.
- if (hr == S_OK)
- {
- if (pContext->IsCalledFromInterop())
- return TRUE;
-
- // If the caller method is NULL and we are not called from interop
- // this is not a normal method access check (e.g. a CA accessibility check)
- // The access check should fail in this case.
- hr = S_FALSE;
-
- MethodDesc* pCallerMD = pContext->GetCallerMethod();
- if (pCallerMD != NULL)
- {
- pIAssemblyName = pCallerMD->GetAssembly()->GetFusionAssemblyName();
- hr = Fusion::Util::IsAnyFrameworkAssembly(pIAssemblyName);
- }
-
- // The caller is not framework code.
- if (hr != S_OK)
- {
- if (m_fThrowIfTargetIsInaccessible)
- ThrowAccessException(pContext, pTargetMT, NULL, TRUE);
- else
- return FALSE;
- }
- }
- }
-
- EX_TRY
- {
- if (m_accessCheckType == kMemberAccess)
- {
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, REFLECTION_MEMBER_ACCESS);
- }
- else
- {
- _ASSERTE(m_accessCheckType == kRestrictedMemberAccess ||
- m_accessCheckType == kUserCodeOnlyRestrictedMemberAccess ||
- (m_accessCheckType == kUserCodeOnlyRestrictedMemberAccessNoTransparency && visibilityCheck));
-
- // JIT guarantees that pTargetMT has been fully loaded and ready to execute by this point, but reflection doesn't.
- // So GetSecurityDescriptor could AV because the DomainAssembly cannot be found.
- // For now we avoid this by calling EnsureActive aggressively. We might want to move this to the reflection code in the future:
- // ReflectionInvocation::PerformVisibilityCheck, PerformSecurityCheckHelper, COMDelegate::BindToMethodName/Info, etc.
- // We don't need to call EnsureInstanceActive because we will be doing access check on all the generic arguments any way so
- // EnsureActive will be called on everyone of them if needed.
- pTargetMT->EnsureActive();
-
- IAssemblySecurityDescriptor * pTargetSecurityDescriptor = pTargetMT->GetModule()->GetSecurityDescriptor();
- _ASSERTE(pTargetSecurityDescriptor != NULL);
-
- if (m_pAccessContext != NULL)
- {
- // If we have a context, use it to do the demand
- Security::ReflectionTargetDemand(REFLECTION_MEMBER_ACCESS,
- pTargetSecurityDescriptor,
- m_pAccessContext);
- }
- else
- {
- // Just do a normal Demand
- Security::ReflectionTargetDemand(REFLECTION_MEMBER_ACCESS, pTargetSecurityDescriptor);
- }
- }
-
- canAccessTarget = TRUE;
- }
- EX_CATCH
- {
- canAccessTarget = FALSE;
-
- if (m_fThrowIfTargetIsInaccessible)
- {
- ThrowAccessException(pContext, pTargetMT, GET_EXCEPTION());
- }
- }
- EX_END_CATCH(RethrowTerminalExceptions);
-
-#endif // FEATURE_CORECLR
#endif // CROSSGEN_COMPILE
return canAccessTarget;
pContextInformation->Append(accessingFrameworkCodeError);
}
-#ifndef FEATURE_CORECLR
- if (isTransparencyError)
- {
- ModuleSecurityDescriptor *pMSD = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pAccessingAssembly);
-
- // If the accessing assembly is APTCA and using level 2 transparency, then transparency errors may be
- // because APTCA newly opts assemblies into being all transparent.
- if (pMSD->IsMixedTransparency() && !pAccessingAssembly->GetSecurityTransparencyBehavior()->DoesUnsignedImplyAPTCA())
- {
- SString callerDisplayName;
- pAccessingAssembly->GetDisplayName(callerDisplayName);
-
- SString level2AptcaTransparencyError;
- EEException::GetResourceMessage(IDS_ACCESS_EXCEPTION_CONTEXT_LEVEL2_APTCA, level2AptcaTransparencyError, callerDisplayName);
-
- pContextInformation->Append(level2AptcaTransparencyError);
- }
-
- // If the assessing assembly is fully transparent and it is partially trusted, then transparency
- // errors may be because the CLR forced the assembly to be transparent due to its trust level.
- if (pMSD->IsAllTransparentDueToPartialTrust())
- {
- _ASSERTE(pMSD->IsAllTransparent());
- SString callerDisplayName;
- pAccessingAssembly->GetDisplayName(callerDisplayName);
- SString partialTrustTransparencyError;
- EEException::GetResourceMessage(IDS_ACCESS_EXCEPTION_CONTEXT_PT_TRANSPARENT, partialTrustTransparencyError, callerDisplayName);
-
- pContextInformation->Append(partialTrustTransparencyError);
- }
- }
-#endif // FEATURE_CORECLR
-
-#if defined(FEATURE_APTCA) && !defined(CROSSGEN_COMPILE)
- // If the target assembly is conditionally APTCA, then it may needed to have been enabled in the domain
- SString conditionalAptcaContext = Security::GetConditionalAptcaAccessExceptionContext(pTargetAssembly);
- if (!conditionalAptcaContext.IsEmpty())
- {
- pContextInformation->Append(conditionalAptcaContext);
- }
-
- // If the target assembly is APTCA killbitted, then indicate that as well
- SString aptcaKillBitContext = Security::GetAptcaKillBitAccessExceptionContext(pTargetAssembly);
- if (!aptcaKillBitContext.IsEmpty())
- {
- pContextInformation->Append(aptcaKillBitContext);
- }
-#endif // FEATURE_APTCA && !CROSSGEN_COMPILE
}
// Generate additional context about the root cause of an access exception which may help in debugging it (for
(pOptionalTargetField ? 1 : 0) +
(pOptionalTargetType ? 1 : 0)));
-#ifndef FEATURE_CORECLR
- if (pTargetMT->GetAssembly()->GetSecurityTransparencyBehavior()->DoesPublicImplyTreatAsSafe())
- {
- // @ telesto: public => TAS in non-coreclr only. The intent is to remove this ifdef and remove
- // public => TAS in all flavors/branches.
- // check if the Target member accessible outside the assembly
- if (IsMdPublic(dwMemberAccess) && IsTypeVisibleOutsideAssembly(pTargetMT))
- {
- return TRUE;
- }
- }
-#endif // !FEATURE_CORECLR
// if the caller [Method] is transparent, do special security checks
// check if security disallows access to target member
// CoreCLR: Do RestrictedMemberAcess visibility checks but bypass transparency checks.
kRestrictedMemberAccessNoTransparency,
-#ifndef FEATURE_CORECLR
- // Used by DynamicMethod with kRestrictedMemberAccess in Win8 immersive mode.
- // Desktop: Equals kNormalAccessibilityChecks for non-framework code calling framework code,
- // kRestrictedMemberAccess otherwise.
- kUserCodeOnlyRestrictedMemberAccess,
-
- // A variation of kUserCodeOnlyRestrictedMemberAccess, but without transparency checks.
- // This is used for reflection invocation in Win8 immersive when all domains on the call stack is full trust.
- // This is an optimization to avoid stackwalks for transparency checks in full trust.
- // Note that both kUserCodeOnlyRestrictedMemberAccess and kUserCodeOnlyRestrictedMemberAccessNoTransparency
- // are needed because we restrict user code from accessing framework internals in Win8 immersive even in full trust.
- kUserCodeOnlyRestrictedMemberAccessNoTransparency
-#endif
};
AccessCheckOptions(
BOOL TransparencyCheckNeeded() const
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return (m_accessCheckType != kNormalAccessNoTransparency && m_accessCheckType != kRestrictedMemberAccessNoTransparency);
-#else //FEATURE_CORECLR
- return (m_accessCheckType != kUserCodeOnlyRestrictedMemberAccessNoTransparency);
-#endif //FEATURE_CORECLR
}
static AccessCheckOptions* s_pNormalAccessChecks;
!throwIfTargetIsInaccessible ||
((pTargetMT ? 1 : 0) + (pTargetMethod ? 1 : 0) + (pTargetField ? 1 : 0)) == 1);
// m_pAccessContext can only be set for kRestrictedMemberAccess
-#ifdef FEATURE_CORECLR
PRECONDITION(m_pAccessContext == NULL ||
accessCheckType == AccessCheckOptions::kRestrictedMemberAccess);
-#else
- PRECONDITION(m_pAccessContext == NULL ||
- accessCheckType == AccessCheckOptions::kUserCodeOnlyRestrictedMemberAccess ||
- accessCheckType == AccessCheckOptions::kRestrictedMemberAccess);
-#endif
}
CONTRACTL_END;
#include "debuginfostore.h"
#include "strsafe.h"
-#ifdef FEATURE_CORECLR
#include "configuration.h"
-#endif
#ifdef _WIN64
#define CHECK_DUPLICATED_STRUCT_LAYOUTS
// Here's the global data for JIT load and initialization state.
JIT_LOAD_DATA g_JitLoadData;
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
// Global that holds the path to custom JIT location
extern "C" LPCWSTR g_CLRJITPath = nullptr;
HRESULT hr = E_FAIL;
-#ifdef FEATURE_CORECLR
PathString CoreClrFolderHolder;
extern HINSTANCE g_hThisInst;
bool havePath = false;
}
}
-#else
- hr = g_pCLRRuntime->LoadLibrary(pwzJitName, phJit);
-#endif
if (SUCCEEDED(hr))
{
EX_TRY
{
bool fContinueToLoadJIT = false;
-#if !defined(FEATURE_CORECLR)
- typedef void (__stdcall* psxsJitStartup) (CoreClrCallbacks const &);
- psxsJitStartup sxsJitStartupFn = (psxsJitStartup) GetProcAddress(*phJit, "sxsJitStartup");
-
- if (sxsJitStartupFn)
- {
- pJitLoadData->jld_status = JIT_LOAD_STATUS_DONE_GET_SXSJITSTARTUP;
-
- CoreClrCallbacks cccallbacks = GetClrCallbacks();
- (*sxsJitStartupFn) (cccallbacks);
-
- pJitLoadData->jld_status = JIT_LOAD_STATUS_DONE_CALL_SXSJITSTARTUP;
- fContinueToLoadJIT = true;
- }
-#else // FEATURE_CORECLR
// For CoreCLR, we never use "sxsJitStartup" as that is Desktop utilcode initialization
// specific. Thus, assume we always got
fContinueToLoadJIT = true;
-#endif // !defined(FEATURE_CORECLR)
if (fContinueToLoadJIT)
{
// Set as a courtesy to code:CorCompileGetRuntimeDll
s_ngenCompilerDll = m_JITCompiler;
-#if (defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)) || (defined(_TARGET_X86_) && defined(FEATURE_CORECLR))
+#if defined(_TARGET_X86_)
// If COMPlus_UseLegacyJit=1, then we fall back to compatjit.dll.
//
// This fallback mechanism was introduced for Visual Studio "14" Preview, when JIT64 (the legacy JIT) was replaced with
// Thus, the COMPlus_useLegacyJit=1 mechanism has been enabled for x86 CoreCLR. This scenario does not have the UseRyuJIT
// registry key, nor the AppX binder mode.
-#if defined(FEATURE_CORECLR)
bool fUseRyuJit = true;
-#else
- bool fUseRyuJit = UseRyuJit();
-#endif
if ((!IsCompilationProcess() || !fUseRyuJit) && // Use RyuJIT for all NGEN, unless we're falling back to JIT64 for everything.
(newJitCompiler != nullptr)) // the main JIT must successfully load before we try loading the fallback JIT
if (!fUsingCompatJit)
{
-#if defined(FEATURE_CORECLR)
DWORD useLegacyJit = Configuration::GetKnobBooleanValue(W("System.JIT.UseWindowsX86CoreLegacyJit"), CLRConfig::EXTERNAL_UseWindowsX86CoreLegacyJit);
-#else
- DWORD useLegacyJit = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_UseLegacyJit); // uncached access, since this code is run no more than one time
-#endif
if (useLegacyJit == 1)
{
fUsingCompatJit = TRUE;
LPCWSTR pwzJitName = NULL;
-#if defined(FEATURE_CORECLR)
#if !defined(CROSSGEN_COMPILE)
if (g_CLRJITPath != nullptr)
{
}
}
#endif // !defined(CROSSGEN_COMPILE)
-#else // !FEATURE_CORECLR
- // Try to obtain a name for the jit library from the env. variable
- IfFailThrow(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_JitName, const_cast<LPWSTR *>(&pwzJitName)));
-#endif // !FEATURE_CORECLR
if (NULL == pwzJitName)
{
else if (index == enum_IDispatchEx)
{
-#ifdef FEATURE_CORECLR
if (AppX::IsAppXProcess())
{
RETURN NULL;
}
-#endif // FEATURE_CORECLR
if (SupportsIReflect(m_pMT))
{
// Keeping the Apollo behaviour also ensures that we allow SL 8.1 scenarios (which do not pass the AppX flag like the modern host)
// to use CorDispatcher for async, in the expected manner, as the OS implementation for CoreDispatcher expects objects to be Agile.
if (!IsAggregated()
-#if !defined(FEATURE_CORECLR)
- && AppX::IsAppXProcess()
-#endif // !defined(FEATURE_CORECLR)
)
{
ComCallWrapperTemplate *pTemplate = GetComCallWrapperTemplate();
}
if (IsIDispatch(riid))
{
-#ifdef FEATURE_CORECLR
if (AppX::IsAppXProcess())
{
RETURN NULL;
}
-#endif // FEATURE_CORECLR
// We don't do visibility checks on IUnknown.
RETURN pWrap->GetIDispatchIP();
SLOT *pComVtable;
unsigned i;
-#ifndef FEATURE_CORECLR
- // Skip this unnecessary expensive check for CoreCLR
- if (!CheckSigTypesCanBeLoaded(pItfClass))
- return FALSE;
-#endif
LOG((LF_INTEROP, LL_INFO1000, "LayOutInterfaceMethodTable: %s, this: %p\n", pItfClass->GetDebugClassName(), this));
GCPROTECT_END();
}
-#ifdef FEATURE_CORECLR
// On the CoreCLR, we don't allow non-fulltrust delegates to be marshaled out (or created: CorHost::CreateDelegate ensures that)
// This helper function checks if we have a full-trust delegate with AllowReversePInvokeCallsAttribute targets.
BOOL COMDelegate::IsFullTrustDelegate(DELEGATEREF pDelegate)
NULL));
#endif // FEATURE_WINDOWSPHONE
}
-#endif // FEATURE_CORECLR
// Marshals a managed method to an unmanaged callback provided the
// managed method is static and it's parameters require no marshalling.
MethodTable* pMT = pDelegate->GetMethodTable();
DelegateEEClass* pClass = (DelegateEEClass*)(pMT->GetClass());
-#ifdef FEATURE_CORECLR
// On the CoreCLR, we only allow marshaling out delegates that we can guarantee are full-trust delegates
if (!IsFullTrustDelegate(pDelegate))
{
TypeString::AppendType(strDelegateType, pMT, TypeString::FormatNamespace | TypeString::FormatAngleBrackets| TypeString::FormatSignature);
COMPlusThrow(kSecurityException, IDS_E_DELEGATE_FULLTRUST_ARPIC_1, strDelegateType.GetUnicode());
}
-#endif
if (pMT->HasInstantiation())
COMPlusThrowArgumentException(W("delegate"), W("Argument_NeedNonGenericType"));
if (pUMEntryThunk->GetDomainId() != GetAppDomain()->GetId())
COMPlusThrow(kNotSupportedException, W("NotSupported_DelegateMarshalToWrongDomain"));
-#ifdef FEATURE_CORECLR
// On the CoreCLR, we only allow marshaling out delegates that we can guarantee are full-trust delegates
if (!IsFullTrustDelegate((DELEGATEREF)pDelegate))
{
COMPlusThrow(kSecurityException, IDS_E_DELEGATE_FULLTRUST_ARPIC_2);
}
-#endif
GCPROTECT_END();
return pDelegate;
MethodDesc *pStubMD = pClass->m_pForwardStubMD;
_ASSERTE(pStubMD != NULL && pStubMD->IsILStub());
-#ifndef FEATURE_CORECLR
- if (pStubMD->AsDynamicMethodDesc()->HasCopyCtorArgs())
- {
- // static stub that gets its arguments in a thread-static field
- pInterceptStub = NDirect::GetStubForCopyCtor();
- }
-#endif // !FEATURE_CORECLR
#ifdef MDA_SUPPORTED
if (MDA_GET_ASSISTANT(PInvokeStackImbalance))
GCPROTECT_END();
#endif // defined(_TARGET_X86_)
-#ifdef FEATURE_CORECLR
// On the CoreCLR, we only allow marshaling out delegates that we can guarantee are full-trust delegates
if (!IsFullTrustDelegate(delObj))
{
COMPlusThrow(kSecurityException, IDS_E_DELEGATE_FULLTRUST_ARPIC_2);
}
-#endif
return delObj;
}
{
// Check whether this is actually a SuppressUnmanagedCodePermission attribute and
// if so, don't do a demand
-#ifndef FEATURE_CORECLR
- MethodTable* pMTMeth = pMeth->GetMethodTable();
- if (pMTMeth->GetMDImport()->GetCustomAttributeByName(pMeth->GetMethodTable()->GetCl(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK ||
- pMTMeth->GetMDImport()->GetCustomAttributeByName(pMeth->GetMemberDef(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK)
-#endif
{
return;
}
}
CONTRACTL_END;
-#ifndef FEATURE_CAS_POLICY
return FALSE;
-#else
- if (pCreatorMethod)
- {
- Assembly* pTargetAssembly = pTargetMD->GetAssembly();
- Assembly* pCreatorAssembly = pCreatorMethod->GetAssembly();
- if (pCreatorAssembly != pTargetAssembly)
- {
- // We don't need secure delegate is everything in the AppDomain is full trust.
- if (!pCreatorDomain->GetSecurityDescriptor()->DomainMayContainPartialTrustCode())
- return FALSE;
-
- IAssemblySecurityDescriptor *pCreatorAsd = pCreatorAssembly->GetSecurityDescriptor(pCreatorDomain);
-
- // We should also create secure delegates for anonymously hosted dynamic methods which
- // are themselves full trust (although transparent) yet can be created from partial trust.
- if (!pCreatorAsd->IsFullyTrusted() ||
- pCreatorAssembly->GetDomainAssembly(pCreatorDomain) == pCreatorDomain->GetAnonymouslyHostedDynamicMethodsAssembly())
- {
- return TRUE;
- }
-
- // Note that if we begin to support using an NGEN image which is not fully trusted, we may need
- // to force on secure delegates as the grant set of the image may not match between NGEN time
- // and runtime.
- }
- }
-
- return FALSE;
-
-#endif // FEATURE_CAS_POLICY
}
BOOL COMDelegate::NeedsWrapperDelegate(MethodDesc* pTargetMD)
}
CONTRACTL_END;
-#ifdef FEATURE_CAS_POLICY
-#error GetSecureInvoke not implemented
-#else
MethodTable * pDelegateMT = pMD->GetMethodTable();
DelegateEEClass* delegateEEClass = (DelegateEEClass*) pDelegateMT->GetClass();
Stub *pStub = delegateEEClass->m_pSecureDelegateInvokeStub;
}
return pStub->GetEntryPoint();
-#endif
}
#else // FEATURE_STUBS_AS_IL
PCODE COMDelegate::GetSecureInvoke(MethodDesc* pMD)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CORECLR
if (GetAppDomain()->GetSecurityDescriptor()->IsFullyTrusted())
return TRUE;
// 1. the delegate is critical and the target method is critical, or
// 2. the delegate is transparent/safecritical and the target method is transparent/safecritical
return (fCriticalDelegate == fCriticalTarget);
-#else
- return TRUE;
-#endif // !FEATURE_CORECLR
}
static BOOL IsTrueMulticastDelegate(OBJECTREF delegate);
-#ifdef FEATURE_CORECLR
static BOOL IsMethodAllowedToSinkReversePInvoke(MethodDesc *pMD);
-#endif
private:
-#ifdef FEATURE_CORECLR
static BOOL IsFullTrustDelegate(DELEGATEREF pDelegate);
-#endif
static Stub* SetupShuffleThunk(MethodTable * pDelMT, MethodDesc *pTargetMeth);
public:
return (INT32)retVal;
}
-#ifndef FEATURE_CORECLR
-/*============================CWSetMarshal============================
-**Action: Helper to set marshal information
-**Returns:
-**Arguments:
-**Exceptions:
-==============================================================================*/
-void QCALLTYPE COMDynamicWrite::SetFieldMarshal(QCall::ModuleHandle pModule, UINT32 tk, LPCBYTE pMarshal, INT32 cbMarshal)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter();
- _ASSERTE(pRCW);
-
- _ASSERTE(pMarshal);
-
- // Define the signature
- IfFailThrow(pRCW->GetEmitter()->SetFieldMarshal(
- tk,
- (PCCOR_SIGNATURE)pMarshal, // marshal blob
- cbMarshal)); // blob length
-
- END_QCALL;
-}
-#endif
/*============================SetConstantValue============================
**Action: Helper to set constant value to field or parameter
*pPeFlags |= ICEE_CREATE_MACHINE_ARM|ICEE_CREATE_FILE_PE32;
}
-#ifndef FEATURE_CORECLR
-//=============================PreSavePEFile=====================================*/
-// PreSave the PEFile
-//==============================================================================*/
-void QCALLTYPE COMDynamicWrite::PreSavePEFile(QCall::ModuleHandle pModule, INT32 portableExecutableKind, INT32 imageFileMachine)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- RefClassWriter *pRCW = pModule->GetReflectionModule()->GetClassWriter();
- _ASSERTE(pRCW);
-
- DWORD peFlags = 0, corhFlags = 0;
- ManagedBitnessFlagsToUnmanagedBitnessFlags(portableExecutableKind, imageFileMachine, &peFlags, &corhFlags);
- IfFailThrow(pRCW->EnsureCeeFileGenCreated(corhFlags, peFlags));
-
- ICeeFileGen *pCeeFileGen = pRCW->GetCeeFileGen();
- HCEEFILE ceeFile = pRCW->GetHCEEFILE();
- _ASSERTE(ceeFile && pCeeFileGen);
-
- // We should not have the on disk emitter yet
- if (pRCW->GetOnDiskEmitter() != NULL)
- pRCW->SetOnDiskEmitter(NULL);
-
- // Get the dispenser.
- SafeComHolderPreemp<IMetaDataDispenserEx> pDisp;
- IfFailThrow(MetaDataGetDispenser(CLSID_CorMetaDataDispenser, IID_IMetaDataDispenserEx, (void**)&pDisp));
-
- //Get the emitter and the importer
- IMetaDataImport *pImport = pRCW->GetRWImporter();
- IMetaDataEmit *pEmit = pRCW->GetEmitter();
- _ASSERTE((pEmit != NULL ) && (pImport != NULL));
-
- // Set the option on the dispenser turn on duplicate check for TypeDef and moduleRef
- VARIANT varOption;
- V_VT(&varOption) = VT_UI4;
- V_I4(&varOption) = MDDupDefault | MDDupTypeDef | MDDupModuleRef | MDDupExportedType | MDDupAssemblyRef | MDDupFile | MDDupAssembly;
- IfFailThrow(pDisp->SetOption(MetaDataCheckDuplicatesFor, &varOption));
-
- V_VT(&varOption) = VT_UI4;
- V_I4(&varOption) = MDRefToDefNone;
- IfFailThrow(pDisp->SetOption(MetaDataRefToDefCheck, &varOption));
-
- V_VT(&varOption) = VT_UI4;
- V_I4(&varOption) = MergeManifest;
- IfFailThrow(pDisp->SetOption(MetaDataMergerOptions, &varOption));
-
- //Define an empty scope
- SafeComHolderPreemp<IMetaDataEmit> pEmitNew;
- IfFailThrow(pDisp->DefineScope(CLSID_CorMetaDataRuntime, 0, IID_IMetaDataEmit, (IUnknown**)&pEmitNew));
-
- // Token can move upon merge. Get the IMapToken from the CeeFileGen that is created for save
- // and pass it to merge to receive token movement notification.
- // Note that this is not a long term fix. We are relying on the fact that those tokens embedded
- // in PE cannot move after the merge. These tokens are TypeDef, TypeRef, MethodDef, FieldDef, MemberRef,
- // TypeSpec, UserString. If this is no longer true, we can break!
- //
- // Note that we don't need to release pIMapToken because it is not AddRef'ed in the GetIMapTokenIfaceEx.
- //
- IUnknown *pUnknown = NULL;
- IfFailThrow(pCeeFileGen->GetIMapTokenIfaceEx(ceeFile, pEmit, &pUnknown));
-
- SafeComHolderPreemp<IMapToken> pIMapToken;
- IfFailThrow(SafeQueryInterfacePreemp(pUnknown, IID_IMapToken, (IUnknown**) &pIMapToken));
-
- // get the unmanaged writer.
- ISymUnmanagedWriter *pWriter = pModule->GetReflectionModule()->GetISymUnmanagedWriter();
- SafeComHolderPreemp<CSymMapToken> pSymMapToken(new CSymMapToken(pWriter, pIMapToken));
-
- //Merge the old tokens into the new (empty) scope
- //This is a copy.
- IfFailThrow(pEmitNew->Merge(pImport, pSymMapToken, NULL));
- IfFailThrow(pEmitNew->MergeEnd());
-
- // Update the Module name in the new scope.
- CQuickArray<WCHAR> cqModuleName;
- ULONG cchName;
-
- IfFailThrow(pImport->GetScopeProps(0, 0, &cchName, 0));
-
- cqModuleName.ReSizeThrows(cchName);
-
- IfFailThrow(pImport->GetScopeProps(cqModuleName.Ptr(), cchName, &cchName, 0));
- IfFailThrow(pEmitNew->SetModuleProps(cqModuleName.Ptr()));
-
- // cache the pEmitNew to RCW!!
- pRCW->SetOnDiskEmitter(pEmitNew);
-
- END_QCALL;
-} // COMDynamicWrite::PreSavePEFile
-
-//=============================SavePEFile=====================================*/
-// Save the PEFile to disk
-//==============================================================================*/
-void QCALLTYPE COMDynamicWrite::SavePEFile(QCall::ModuleHandle pModule, LPCWSTR wszPeName, UINT32 entryPoint, UINT32 fileKind, BOOL isManifestFile)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- HRESULT hr=S_OK;
- HCORENUM hTypeDefs=0;
- mdTypeDef td;
- ULONG count;
- IMetaDataImport *pImportNew = 0;
- ULONG newMethRVA;
- DWORD metaDataSize;
- BYTE *metaData;
- ULONG metaDataOffset;
- HCEESECTION pILSection;
- ISymUnmanagedWriter *pWriter = NULL;
-
- if (wszPeName==NULL)
- COMPlusThrow(kArgumentNullException, W("ArgumentNull_String"));
- if (wszPeName[0] == '\0')
- COMPlusThrow(kFormatException, W("Format_StringZeroLength"));
-
- Assembly * pAssembly = pModule->GetAssembly();
- _ASSERTE( pAssembly );
-
- RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter();
- _ASSERTE(pRCW);
-
- ICeeFileGen * pCeeFileGen = pRCW->GetCeeFileGen();
- HCEEFILE ceeFile = pRCW->GetHCEEFILE();
- _ASSERTE(ceeFile && pCeeFileGen);
-
- IMetaDataEmit * pEmitNew = pRCW->GetOnDiskEmitter();
- _ASSERTE(pEmitNew);
-
- //Get the emitter and the importer
-
- if (pAssembly->IsDynamic() && isManifestFile)
- {
- // manifest is stored in this file
-
- // Allocate space for a strong name signature if an originator was supplied
- // (this doesn't strong name the assembly, but it makes it possible to do so
- // as a post processing step).
- if (pAssembly->IsStrongNamed())
- IfFailGo(pAssembly->AllocateStrongNameSignature(pCeeFileGen, ceeFile));
- }
-
- //Set the Output FileName
- IfFailGo( pCeeFileGen->SetOutputFileName(ceeFile, (LPWSTR)wszPeName) );
-
- //Set the Entry Point or throw the dll switch if we're creating a dll.
- if (entryPoint!=0)
- {
- IfFailGo( pCeeFileGen->SetEntryPoint(ceeFile, entryPoint) );
- }
-
- switch (fileKind)
- {
- case Dll:
- {
- IfFailGo( pCeeFileGen->SetDllSwitch(ceeFile, true) );
- break;
- }
- case WindowApplication:
- {
- // window application. Set the SubSystem
- IfFailGo( pCeeFileGen->SetSubsystem(ceeFile, IMAGE_SUBSYSTEM_WINDOWS_GUI, CEE_IMAGE_SUBSYSTEM_MAJOR_VERSION, CEE_IMAGE_SUBSYSTEM_MINOR_VERSION) );
- break;
- }
- case ConsoleApplication:
- {
- // Console application. Set the SubSystem
- IfFailGo( pCeeFileGen->SetSubsystem(ceeFile, IMAGE_SUBSYSTEM_WINDOWS_CUI, CEE_IMAGE_SUBSYSTEM_MAJOR_VERSION, CEE_IMAGE_SUBSYSTEM_MINOR_VERSION) );
- break;
- }
- default:
- {
- _ASSERTE(!"Unknown file kind!");
- break;
- }
- }
-
- IfFailGo( pCeeFileGen->GetIlSection(ceeFile, &pILSection) );
- IfFailGo( pEmitNew->GetSaveSize(cssAccurate, &metaDataSize) );
- IfFailGo( pCeeFileGen->GetSectionBlock(pILSection, metaDataSize, sizeof(DWORD), (void**) &metaData) );
- IfFailGo( pCeeFileGen->GetSectionDataLen(pILSection, &metaDataOffset) );
- metaDataOffset -= metaDataSize;
-
- // get the unmanaged writer.
- pWriter = pModule->GetReflectionModule()->GetISymUnmanagedWriter();
- IfFailGo( EmitDebugInfoBegin(pModule, pCeeFileGen, ceeFile, pILSection, wszPeName, pWriter) );
-
- if (pAssembly->IsDynamic() && pRCW->m_ulResourceSize)
- {
- // There are manifest in this file
-
- IfFailGo( pCeeFileGen->GetMethodRVA(ceeFile, 0, &newMethRVA) );
-
- // Point to manifest resource
- IfFailGo( pCeeFileGen->SetManifestEntry( ceeFile, pRCW->m_ulResourceSize, newMethRVA ) );
- }
-
- IfFailGo( pCeeFileGen->LinkCeeFile(ceeFile) );
-
- // Get the import interface from the new Emit interface.
- IfFailGo( pEmitNew->QueryInterface(IID_IMetaDataImport, (void **)&pImportNew));
-
-
- //Enumerate the TypeDefs and update method RVAs.
- while ((hr = pImportNew->EnumTypeDefs( &hTypeDefs, &td, 1, &count)) == S_OK)
- {
- UpdateMethodRVAs(pEmitNew, pImportNew, pCeeFileGen, ceeFile, td, pModule->GetReflectionModule()->m_sdataSection);
- }
-
- if (hTypeDefs)
- {
- pImportNew->CloseEnum(hTypeDefs);
- }
- hTypeDefs=0;
-
- //Update Global Methods.
- UpdateMethodRVAs(pEmitNew, pImportNew, pCeeFileGen, ceeFile, 0, pModule->GetReflectionModule()->m_sdataSection);
-
-
- //Emit the MetaData
- // IfFailGo( pCeeFileGen->EmitMetaDataEx(ceeFile, pEmitNew));
- IfFailGo( pCeeFileGen->EmitMetaDataAt(ceeFile, pEmitNew, pILSection, metaDataOffset, metaData, metaDataSize) );
-
- // finish the debugging info emitting after the metadata save so that token remap will be caught correctly
- IfFailGo( EmitDebugInfoEnd(pModule, pCeeFileGen, ceeFile, pILSection, wszPeName, pWriter) );
-
- //Generate the CeeFile
- IfFailGo(pCeeFileGen->GenerateCeeFile(ceeFile) );
-
- // Strong name sign the resulting assembly if required.
- if (pAssembly->IsDynamic() && isManifestFile && pAssembly->IsStrongNamed())
- IfFailGo(pAssembly->SignWithStrongName((LPWSTR)wszPeName));
-
-ErrExit:
-
- pRCW->SetOnDiskEmitter(NULL);
-
- //Release the interfaces. This should free some of the associated resources.
- if (pImportNew)
- pImportNew->Release();
-
- //Release our interfaces if we allocated them to begin with
- pRCW->DestroyCeeFileGen();
-
- //Check all file IO errors. If so, throw IOException. Otherwise, just throw the hr.
- if (FAILED(hr))
- {
- if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
- {
- if (IsWin32IOError(HRESULT_CODE(hr)))
- {
- SString hrMessage;
- GenerateTopLevelHRExceptionMessage(hr, hrMessage);
- COMPlusThrowHR(COR_E_IO, IDS_EE_GENERIC, hrMessage.GetUnicode());
- }
- else
- {
- COMPlusThrowHR(hr);
- }
- }
- COMPlusThrowHR(hr);
- }
-
- END_QCALL;
-}
-
-#endif // FEATURE_CORECLR
//=============================EmitDebugInfoBegin============================*/
// Phase 1 of emit debugging directory and symbol file.
}
-#ifndef FEATURE_CORECLR
-//==============================================================================
-// Define external file for native resource.
-//==============================================================================
-void QCALLTYPE COMDynamicWrite::DefineNativeResourceFile(QCall::ModuleHandle pModule, LPCWSTR pwzFileName, INT32 portableExecutableKind, INT32 imageFileMachine)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter();
- _ASSERTE(pRCW);
-
- DWORD peFlags = 0, corhFlags = 0;
- ManagedBitnessFlagsToUnmanagedBitnessFlags(portableExecutableKind, imageFileMachine, &peFlags, &corhFlags);
- IfFailThrow( pRCW->EnsureCeeFileGenCreated(corhFlags, peFlags) );
-
- ICeeFileGen * pCeeFileGen = pRCW->GetCeeFileGen();
- HCEEFILE ceeFile = pRCW->GetHCEEFILE();
- _ASSERTE(ceeFile && pCeeFileGen);
-
- // Set the resource file name.
- IfFailThrow( pCeeFileGen->SetResourceFileName(ceeFile, (LPWSTR)pwzFileName) );
-
- END_QCALL;
-} // void __stdcall COMDynamicWrite::DefineNativeResourceFile()
-
-//==============================================================================
-// Define array of bytes for native resource.
-//==============================================================================
-void QCALLTYPE COMDynamicWrite::DefineNativeResourceBytes(QCall::ModuleHandle pModule, LPCBYTE pbResource, INT32 cbResource, INT32 portableExecutableKind, INT32 imageFileMachine)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter();
- _ASSERTE(pRCW);
-
- DWORD peFlags = 0, corhFlags = 0;
- ManagedBitnessFlagsToUnmanagedBitnessFlags(portableExecutableKind, imageFileMachine, &peFlags, &corhFlags);
- IfFailThrow( pRCW->EnsureCeeFileGenCreated(corhFlags, peFlags) );
-
- ICeeFileGen * pCeeFileGen = pRCW->GetCeeFileGen();
- HCEEFILE ceeFile = pRCW->GetHCEEFILE();
- _ASSERTE(ceeFile && pCeeFileGen);
-
- // Set the resource stream.
- HCEESECTION ceeSection = NULL;
- IfFailThrow( pCeeFileGen->GetSectionCreate(ceeFile, ".rsrc", sdReadOnly, &ceeSection) );
-
- void * pvResource;
- IfFailThrow( pCeeFileGen->GetSectionBlock(ceeSection, cbResource, 1, &pvResource) );
- memcpy(pvResource, pbResource, cbResource);
-
- END_QCALL;
-} // void __stdcall COMDynamicWrite::DefineNativeResourceBytes()
-
-//=============================AddResource=====================================*/
-// ecall for adding embedded resource to this module
-//==============================================================================*/
-void QCALLTYPE COMDynamicWrite::AddResource(QCall::ModuleHandle pModule, LPCWSTR pName, LPCBYTE pResBytes, INT32 resByteCount, UINT32 uFileTk, UINT32 iAttribute, INT32 portableExecutableKind, INT32 imageFileMachine)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter();
- _ASSERTE(pRCW);
-
- DWORD peFlags = 0, corhFlags = 0;
- ManagedBitnessFlagsToUnmanagedBitnessFlags(portableExecutableKind, imageFileMachine, &peFlags, &corhFlags);
- IfFailThrow( pRCW->EnsureCeeFileGenCreated(corhFlags, peFlags) );
-
- Assembly * pAssembly = pModule->GetAssembly();
- _ASSERTE( pAssembly && pAssembly->IsDynamic() );
-
- ICeeFileGen * pCeeFileGen = pRCW->GetCeeFileGen();
- HCEEFILE ceeFile = pRCW->GetHCEEFILE();
- _ASSERTE(ceeFile && pCeeFileGen);
-
- IMetaDataEmit * pOnDiskEmit = pRCW->GetOnDiskEmitter();
-
- // First, put it into .rdata section. The only reason that we choose .rdata section at
- // this moment is because this is the first section on the PE file. We don't need to deal with
- // reloc. Actually, I don't know how to deal with the reloc with CeeFileGen given that the reloc
- // position is not in the same file!
-
- // Get the .rdata section
- HCEESECTION hSection;
- IfFailThrow( pCeeFileGen->GetRdataSection(ceeFile, &hSection) );
-
- // the current section data length is the RVA
- ULONG ulOffset;
- IfFailThrow( pCeeFileGen->GetSectionDataLen(hSection, &ulOffset) );
-
- // Allocate a block of space fromt he .rdata section
- BYTE * pbBuffer;
- IfFailThrow( pCeeFileGen->GetSectionBlock(
- hSection, // from .rdata section
- resByteCount + sizeof(DWORD), // number of bytes that we need
- 1, // alignment
- (void**) &pbBuffer) );
-
- // now copy over the resource
- memcpy( pbBuffer, &resByteCount, sizeof(DWORD) );
- memcpy( pbBuffer + sizeof(DWORD), pResBytes, resByteCount );
-
- // track the total resource size so far. The size is actually the offset into the section
- // after writing the resource out
- IfFailThrow( pCeeFileGen->GetSectionDataLen(hSection, &pRCW->m_ulResourceSize) );
-
- mdFile tkFile = RidFromToken(uFileTk) ? uFileTk : mdFileNil;
- mdManifestResource mr;
-
- if (tkFile != mdFileNil)
- {
- SafeComHolderPreemp<IMetaDataAssemblyEmit> pOnDiskAssemblyEmit;
-
- IfFailThrow( pOnDiskEmit->QueryInterface(IID_IMetaDataAssemblyEmit, (void **) &pOnDiskAssemblyEmit) );
-
- // The resource is stored in a file other than the manifest file
- IfFailThrow(pOnDiskAssemblyEmit->DefineManifestResource(
- pName,
- mdFileNil, // implementation -- should be file token of this module in the manifest
- ulOffset, // offset to this file -- need to be adjusted upon save
- iAttribute, // resource flag
- &mr)); // manifest resource token
- }
-
- // Add an entry into the ManifestResource table for this resource
- // The RVA is ulOffset
- SafeComHolderPreemp<IMetaDataAssemblyEmit> pAssemEmitter(pAssembly->GetOnDiskMDAssemblyEmitter());
- IfFailThrow(pAssemEmitter->DefineManifestResource(
- pName,
- tkFile, // implementation -- should be file token of this module in the manifest
- ulOffset, // offset to this file -- need to be adjusted upon save
- iAttribute, // resource flag
- &mr)); // manifest resource token
-
- pRCW->m_tkFile = tkFile;
-
- END_QCALL;
-}
-
-#endif // FEATURE_CORECLR
//============================AddDeclarativeSecurity============================*/
// Add a declarative security serialized blob and a security action code to a
static
void QCALLTYPE SavePEFile(QCall::ModuleHandle pModule, LPCWSTR wszPeName, UINT32 entryPoint, UINT32 fileKind, BOOL isManifestFile);
-#ifndef FEATURE_CORECLR
- static
- void QCALLTYPE DefineNativeResourceFile(QCall::ModuleHandle pModule, LPCWSTR pwzFileName, INT32 portableExecutableKind, INT32 imageFileMachine);
-
- static
- void QCALLTYPE DefineNativeResourceBytes(QCall::ModuleHandle pModule, LPCBYTE pbResource, INT32 cbResource, INT32 portableExecutableKind, INT32 imageFileMachine);
-
- static
- void QCALLTYPE AddResource(QCall::ModuleHandle pModule, LPCWSTR pName, LPCBYTE pResBytes, INT32 resByteCount, UINT32 uFileTk, UINT32 iAttribute, INT32 portableExecutableKind, INT32 imageFileMachine);
-#endif // !FEATURE_CORECLR
// not an ecall!
static HRESULT EmitDebugInfoBegin(
static
INT32 QCALLTYPE SetParamInfo(QCall::ModuleHandle pModule, UINT32 tkMethod, UINT32 iSequence, UINT32 iAttributes, LPCWSTR wszParamName);
-#ifndef FEATURE_CORECLR
- // functions to set FieldMarshal
- static
- void QCALLTYPE SetFieldMarshal(QCall::ModuleHandle pModule, UINT32 tk, LPCBYTE pMarshal, INT32 cbMarshal);
-#endif
// functions to set default value
static
void QCALLTYPE SetConstantValue(QCall::ModuleHandle pModule, UINT32 tk, DWORD valueType, LPVOID pValue);
}
else
{
-#ifdef FEATURE_CORECLR
_ASSERTE(!"NYI");
COMPlusThrowHR(COR_E_NOTSUPPORTED);
-#else // FEATURE_CORECLR
- // TODO: probably we can cache the object on a per App domain bases
- // using CCW as the key
- OBJECTREF pwrap = NULL;
- GCPROTECT_BEGIN(pwrap);
- {
- pwrap = GetCCWObject();
- oref = AppDomainHelper::CrossContextCopyFrom(m_dwServerDomainId, &pwrap);
- }
- GCPROTECT_END();
-#endif // FEATURE_CORECLR
}
return oref;
DWORD dwRet;
{
// m_hLock is a mutex
-#ifndef FEATURE_CORECLR
- Thread::BeginThreadAffinityAndCriticalRegion();
-#endif
dwRet = WaitForSingleObject(m_hLock, INFINITE);
}
InterlockedDecrement((LPLONG)&m_dwNumLocks);
#endif
-#ifndef FEATURE_CORECLR
- Thread::EndThreadAffinityAndCriticalRegion();
-#endif
}
#endif
//
ESymbolFormat symFormatToUse = eSymbolFormatILDB;
-#ifndef FEATURE_CORECLR // On desktop only we still use PDB format if the symbols are savable to disk
- if(mod->GetAssembly()->HasSaveAccess())
- {
- symFormatToUse = eSymbolFormatPDB;
- }
-#endif
static ConfigDWORD dbgForcePDBSymbols;
if(dbgForcePDBSymbols.val_DontUse_(W("DbgForcePDBSymbols"), 0) == 1)
{
LPCWSTR fileName = pModule->GetPath();
if (*fileName != 0) {
-#ifndef FEATURE_CORECLR
- // workaround - lie about where mscorlib is. Mscorlib is now loaded out of the GAC,
- // but some apps query its location to find the system directory. (Notably CodeDOM)
- if (pModule->IsSystem())
- retString.Set(SystemDomain::System()->BaseLibrary());
- else
-#endif // !FEATURE_CORECLR
{
#ifdef FEATURE_WINDOWSPHONE
//
RETURN(OBJECTREFToObject(refArrClasses));
}
-#if defined(FEATURE_X509) && defined(FEATURE_CAS_POLICY)
-//+--------------------------------------------------------------------------
-//
-// Member: COMModule::GetSignerCertificate()
-//
-// Synopsis: Gets the certificate with which the module was signed.
-//
-// Effects: Creates an X509Certificate and returns it.
-//
-// Arguments: None.
-//
-// Returns: OBJECTREF to an X509Certificate object containing the
-// signer certificate.
-//
-//---------------------------------------------------------------------------
-
-void QCALLTYPE COMModule::GetSignerCertificate(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retData)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- PCOR_TRUST pCorTrust = NULL;
- IAssemblySecurityDescriptor* pSecDesc = NULL;
- PBYTE pbSigner = NULL;
- DWORD cbSigner = 0;
-
- // ******** Get the security descriptor ********
-
- // Get a pointer to the module security descriptor
- pSecDesc = pModule->GetSecurityDescriptor();
- _ASSERTE(pSecDesc);
-
- // ******** Get COR_TRUST info from module security descriptor ********
- if (FAILED(pSecDesc->LoadSignature(&pCorTrust)))
- {
- COMPlusThrow(kArgumentNullException, W("InvalidOperation_MetaDataError"));
- }
-
- if( pCorTrust )
- {
- // Get a pointer to the signer certificate information in the COR_TRUST
- pbSigner = pCorTrust->pbSigner;
- cbSigner = pCorTrust->cbSigner;
-
- if( pbSigner && cbSigner )
- {
- retData.SetByteArray(pbSigner, cbSigner);
- }
- }
-
- END_QCALL;
-}
-#endif // #if defined(FEATURE_X509) && defined(FEATURE_CAS_POLICY)
FCIMPL1(FC_BOOL_RET, COMModule::IsResource, ReflectModuleBaseObject* pModuleUNSAFE)
{
}
FCIMPLEND
-#ifdef FEATURE_CORECLR
//---------------------------------------------------------------------
// Helper code for PunkSafeHandle class. This does the Release in the
return (void*)DReleaseTarget;
}
FCIMPLEND
-#endif //FEATURE_CORECLR
static
mdString QCALLTYPE GetStringConstant(QCall::ModuleHandle pModule, LPCWSTR pwzValue, INT32 iLength);
-#if defined(FEATURE_X509) && defined(FEATURE_CAS_POLICY)
- /*X509Certificate*/
- static
- void QCALLTYPE GetSignerCertificate(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retData);
-#endif // #if defined(FEATURE_X509) && defined(FEATURE_CAS_POLICY)
static
void QCALLTYPE SetModuleName(QCall::ModuleHandle pModule, LPCWSTR wszModuleName);
class COMPunkSafeHandle
{
public:
-#ifdef FEATURE_CORECLR
static FCDECL0(void*, nGetDReleaseTarget);
-#endif
};
#endif
#include "compatibilityflags.h"
extern BOOL GetCompatibilityFlag(CompatibilityFlag flag);
-#ifndef FEATURE_CORECLR
-extern DWORD* GetGlobalCompatibilityFlags();
-#endif // !FEATURE_CORECLR
#include "strongname.h"
#include "stdmacros.h"
STATIC_CONTRACT_GC_NOTRIGGER;
STATIC_CONTRACT_CAN_TAKE_LOCK;
-#ifndef FEATURE_CORECLR
- if (CLRTaskHosted()) {
- Thread::BeginThreadAffinity();
- }
-#endif // !FEATURE_CORECLR
UnsafeEnterCriticalSection(lpCriticalSection);
INCTHREADLOCKCOUNT();
}
UnsafeLeaveCriticalSection(lpCriticalSection);
DECTHREADLOCKCOUNT();
-#ifndef FEATURE_CORECLR
- if (CLRTaskHosted()) {
- Thread::EndThreadAffinity();
- }
-#endif // !FEATURE_CORECLR
}
inline BOOL UnsafeEETryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
#include "zapsig.h"
#include "gcrefmap.h"
-#ifndef FEATURE_CORECLR
-#include "corsym.h"
-#endif // FEATURE_CORECLR
#include "virtualcallstub.h"
#include "typeparse.h"
ENTER_DOMAIN_PTR(pCompilationDomain,ADV_COMPILATION)
{
-#ifdef FEATURE_CORECLR
if (fForceFulltrustDomain)
((ApplicationSecurityDescriptor *)pCompilationDomain->GetSecurityDescriptor())->SetGrantedPermissionSet(NULL, NULL, 0xFFFFFFFF);
-#endif
#ifndef CROSSGEN_COMPILE
-#ifndef FEATURE_CORECLR
- pCompilationDomain->InitializeHashing(NULL);
-#endif // FEATURE_CORECLR
#endif
pCompilationDomain->InitializeDomainContext(TRUE, NULL, NULL);
#ifndef CROSSGEN_COMPILE
-#ifdef FEATURE_CORECLR
if (!NingenEnabled())
{
initializeSecurity.Call(args);
GCPROTECT_END();
}
-#endif //FEATURE_CORECLR
#endif
{
PEImageHolder pImage;
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- // If the path is not absolute, look for the assembly on platform path list first
- if (wcschr(wzPath, '\\') == NULL || wcschr(wzPath, ':') == NULL || wcschr(wzPath, '/') == NULL)
- {
- CompilationDomain::FindImage(wzPath,
- fExplicitBindToNativeImage ? MDInternalImport_NoCache : MDInternalImport_Default, &pImage);
- }
-#endif
if (pImage == NULL)
{
pDomain->AddAssemblyToCache(&spec, pDomainAssembly);
#endif
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- if (!IsReadyToRunCompilation())
- pDomain->ToCompilationDomain()->ComputeAssemblyHardBindList(pAssemblyHolder->GetPersistentMDImport());
-#endif
{
// Mark the assembly before it gets fully loaded and NGen image dependencies are verified. This is necessary
return S_OK;
}
-#ifndef FEATURE_CORECLR
-BOOL CEECompileInfo::SupportsAutoNGen(CORINFO_ASSEMBLY_HANDLE assembly)
-{
- STANDARD_VM_CONTRACT;
-
- Assembly *pAssembly = (Assembly*) assembly;
- return pAssembly->SupportsAutoNGen();
-}
-
-HRESULT CEECompileInfo::SetCachedSigningLevel(HANDLE hNI, HANDLE *pModules, COUNT_T nModules)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
-
- HMODULE hKernel32 = WszLoadLibrary(W("kernel32.dll"));
- typedef BOOL (WINAPI *SetCachedSigningLevel_t)
- (__in_ecount(Count) PHANDLE SourceFiles, __in ULONG Count, __in ULONG Flags, __in HANDLE TargetFile);
- SetCachedSigningLevel_t SetCachedSigningLevel
- = (SetCachedSigningLevel_t)GetProcAddress(hKernel32, "SetCachedSigningLevel");
- if (SetCachedSigningLevel == NULL)
- {
- return S_OK;
- }
-
- StackSArray<PEImage*> images;
- PEImage::GetAll(images);
-
- StackSArray<HANDLE> handles;
- for (StackSArray<PEImage*>::Iterator i = images.Begin(), end = images.End(); i != end; i++)
- {
- if (!(*i)->IsFile())
- {
- continue;
- }
- HANDLE hFile = (*i)->GetFileHandleLocking();
- handles.Append(hFile);
- }
-
- if (!SetCachedSigningLevel(handles.GetElements(), handles.GetCount(), 0, hNI))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FAILED(hr));
- goto ErrExit;
- }
-
- for (COUNT_T i = 0; i < nModules; i++)
- {
- if (!SetCachedSigningLevel(handles.GetElements(), handles.GetCount(), 0, pModules[i]))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FAILED(hr));
- goto ErrExit;
- }
- }
-
-ErrExit:
- return hr;
-}
-#endif
BOOL CEECompileInfo::CheckAssemblyZap(
CORINFO_ASSEMBLY_HANDLE assembly,
LIMITED_METHOD_CONTRACT;
}
-#ifdef FEATURE_CORECLR
#define WRITER_LOAD_ERROR_MESSAGE W("Unable to load ") NATIVE_SYMBOL_READER_DLL W(". Please ensure that ") NATIVE_SYMBOL_READER_DLL W(" is on the path. Error='%d'\n")
-#else
-#define WRITER_LOAD_ERROR_MESSAGE W("Unable to load diasymreader.dll. Please ensure that version 11 or greater of diasymreader.dll is on the path. You can typically find this DLL in the desktop .NET install directory for 4.5 or greater. Error='%d'\n")
-#endif
HRESULT Load(LPCWSTR wszDiasymreaderPath = nullptr)
{
{
hr = FakeCoCreateInstanceEx(
CLSID_CorSymBinder_SxS,
-#ifdef FEATURE_CORECLR
wszDiasymreaderPath != nullptr ? wszDiasymreaderPath : (LPCWSTR)NATIVE_SYMBOL_READER_DLL,
-#else
- wszDiasymreaderPath,
-#endif
IID_ISymUnmanagedBinder,
(void**)&m_pBinder,
NULL);
{
STANDARD_VM_CONTRACT;
-#ifndef FEATURE_CORECLR // hardbinding
- GetAppDomain()->ToCompilationDomain()->SetAssemblyHardBindList(pHardBindList, cHardBindList);
-#endif
}
HRESULT CEECompileInfo::SetVerboseLevel(
{
STANDARD_VM_CONTRACT;
-#ifndef FEATURE_CORECLR // hardbinding
- m_hardBoundModules.Init(FALSE, NULL);
- m_cantHardBindModules.Init(FALSE, NULL);
- m_useHardBindList = FALSE;
-#endif
}
void CompilationDomain::ReleaseDependencyEmitter()
Security::SetDefaultAppDomainProperty(GetSecurityDescriptor());
SetCompilationDomain();
-#ifndef FEATURE_CORECLR
- // We need the Compilation Domain to be homogeneous. We've already forced everything to be full trust.
- // However, CheckZapSecurity needs this to be set, so set it here.
- GetSecurityDescriptor()->SetHomogeneousFlag(TRUE);
-#endif // !FEATURE_CORECLR
#ifdef _DEBUG
g_pConfig->DisableGenerateStubForHost();
pDependency->dwAssemblyDef = def;
pDependency->signNativeImage = INVALID_NGEN_SIGNATURE;
-#ifdef FEATURE_APTCA
- pDependency->dependencyInfo = CorCompileDependencyInfo(0);
-#endif //FEATURE_APTCA
if (pFile)
{
// Note that this can trigger an assembly load (of mscorlib)
pAssembly->GetOptimizedIdentitySignature(&pDependency->signAssemblyDef);
-#if defined(FEATURE_APTCA) || !defined(FEATURE_CORECLR)
- ReleaseHolder<IMDInternalImport> pAssemblyMD(pFile->GetMDImportWithRef());
-#endif
-
-#ifdef FEATURE_APTCA
- // determine if there's an APTCA reference, before we retrieve the target file version (for killbit)
- TokenSecurityDescriptorFlags assemblySecurityAttributes =
- TokenSecurityDescriptor::ReadSecurityAttributes(pAssemblyMD, TokenFromRid(1, mdtAssembly));
- pFile->AddRef();
- BOOL fIsAptca = assemblySecurityAttributes & (TokenSecurityDescriptorFlags_APTCA
- | TokenSecurityDescriptorFlags_ConditionalAPTCA);
- if (fIsAptca)
- {
- // get the file path
- LPCWSTR pwszPath = pFile->GetPath().GetUnicode();
- if (pwszPath == NULL)
- {
- return E_FAIL;
- }
- // retrieve the file version based on the file path (using Watson OS wrapper)
- if (FAILED(GetFileVersion(pwszPath, &pDependency->uliFileVersion)))
- // ignore failures (e.g. platform doesn't support file version, or version info missing
-
- {
- fIsAptca = FALSE;
- }
- }
- if (fIsAptca)
- {
- pDependency->dependencyInfo = CorCompileDependencyInfo(pDependency->dependencyInfo
- | CORCOMPILE_DEPENDENCY_IS_APTCA);
- }
-
- if (assemblySecurityAttributes & TokenSecurityDescriptorFlags_ConditionalAPTCA)
- {
- pDependency->dependencyInfo = CorCompileDependencyInfo(pDependency->dependencyInfo
- | CORCOMPILE_DEPENDENCY_IS_CAPTCA);
- }
-#endif //FEATURE_APTCA
-
-#ifdef FEATURE_CORECLR // hardbinding
//
// This is done in CompilationDomain::CanEagerBindToZapFile with full support for hardbinding
//
CORCOMPILE_VERSION_INFO * pNativeVersion = pFile->GetLoadedNative()->GetNativeVersionInfo();
pDependency->signNativeImage = pNativeVersion->signature;
}
-#endif
-
-#ifndef FEATURE_CORECLR
- // Find the architecture of the dependency, using algorithm from Fusion GetRuntimeVersionForAssembly.
- // Normally, when an assembly is loaded at runtime, Fusion determines its architecture based on the
- // metadata. However, if assembly load is skipped due to presence of native image, then Fusion needs
- // to get assembly architecture from another source. For assemblies in GAC, the GAC structure provides
- // architecture data. For assemblies outside of GAC, however, no other source of info is available.
- // So we calculate the architecture now and store it in the native image, to make it available to Fusion.
- // The algorithm here must exactly match the algorithm in GetRuntimeVersionForAssembly.
- LPCSTR pszPERuntime;
- IfFailThrow(pAssemblyMD->GetVersionString(&pszPERuntime));
-
- if (SString::_strnicmp(pszPERuntime, "v1.0", 4) != 0 &&
- SString::_strnicmp(pszPERuntime, "v1.1", 4) != 0 &&
- SString::_stricmp(pszPERuntime, "Standard CLI 2002") != 0)
- {
- // Get the PE architecture of this dependency, similar to PEAssembly::GetFusionProcessorArchitecture.
- // The difference is when NI is loaded, PEAssembly::GetFusionProcessorArchitecture returns the
- // architecture of the NI (which is never processor neutral), but we want the architecture
- // associated with the IL image.
- DWORD dwPEKind, dwMachine;
- if (pFile->HasNativeImage())
- {
- // CrossGen can load an NI without loading the corresponding IL image, in which case
- // PEAssembly::GetILImage() actually returns an NI. Thus we need specific code to handle NI.
- PEImageHolder pImage(pFile->GetNativeImageWithRef());
- pImage->GetNativeILPEKindAndMachine(&dwPEKind, &dwMachine);
- }
- else
- {
- pFile->GetILimage()->GetPEKindAndMachine(&dwPEKind, &dwMachine);
- }
- DWORD dwAssemblyFlags = 0;
- IfFailThrow(pAssemblyMD->GetAssemblyProps(TokenFromRid(1, mdtAssembly),
- NULL, NULL, NULL,
- NULL, NULL, &dwAssemblyFlags));
-
- PEKIND peKind;
- if (SUCCEEDED(TranslatePEToArchitectureType(
- (CorPEKind)dwPEKind,
- dwMachine,
- dwAssemblyFlags,
- &peKind)))
- {
- CorCompileDependencyInfo peKindShifted = CorCompileDependencyInfo(peKind << CORCOMPILE_DEPENDENCY_PEKIND_SHIFT);
- _ASSERTE(peKindShifted == (peKindShifted & CORCOMPILE_DEPENDENCY_PEKIND_MASK));
- pDependency->dependencyInfo = CorCompileDependencyInfo(pDependency->dependencyInfo
- | (peKindShifted & CORCOMPILE_DEPENDENCY_PEKIND_MASK));
- }
- }
-#endif //FEATURE_FUSION
}
return S_OK;
return (pEntry != NULL) ? pEntry->m_pRef : NULL;
}
-#ifndef FEATURE_CORECLR // hardbinding
-//----------------------------------------------------------------------------
-// Was the assembly asked to be hard-bound to?
-
-BOOL CompilationDomain::IsInHardBindRequestList(Assembly * pAssembly)
-{
- return IsInHardBindRequestList(pAssembly->GetManifestFile());
-}
-
-BOOL CompilationDomain::IsInHardBindRequestList(PEAssembly * pAssembly)
-{
- if (!m_useHardBindList)
- return FALSE;
-
- StackSString displayName;
- pAssembly->GetDisplayName(displayName);
-
- for (COUNT_T i = 0; i < m_assemblyHardBindList.GetCount(); i++)
- {
- if (displayName.Equals(m_assemblyHardBindList[i]))
- return TRUE;
- }
-
- return FALSE;
-}
-
-BOOL CompilationDomain::IsSafeToHardBindTo(PEAssembly * pAssembly)
-{
- WRAPPER_NO_CONTRACT;
- // The dependency worker does not have m_useHardBindList set.
- // We do want to allow all possible native images to be loaded in this case.
- if (!m_useHardBindList)
- return TRUE;
-
- if (CompilationDomain::IsInHardBindRequestList(pAssembly))
- return TRUE;
-
- return FALSE;
-}
-
-PtrHashMap::PtrIterator CompilationDomain::IterateHardBoundModules()
-{
- WRAPPER_NO_CONTRACT;
- return m_hardBoundModules.begin();
-}
-
-void CompilationDomain::SetAssemblyHardBindList(
- __in_ecount( cHardBindList )
- LPWSTR *pHardBindList,
- DWORD cHardBindList)
-{
- m_assemblyHardBindList.SetCount(0);
-
- for (DWORD i = 0; i < cHardBindList; i++)
- {
- SString s(pHardBindList[i]);
- m_assemblyHardBindList.Append(s);
- }
-
- m_useHardBindList = TRUE;
-}
-#endif // FEATURE_CORECLR
//----------------------------------------------------------------------------
// Is it OK to embed direct pointers to an ngen dependency?
return TRUE;
}
-#ifdef FEATURE_CORECLR // hardbinding
//
// CoreCLR does not have attributes for fine grained eager binding control.
// We hard bind to mscorlib.dll only.
//
return targetModule->IsSystem();
-#else
- // Now, look up the hashtables to avoid doing the heavy-duty work everytime
-
- if (m_cantHardBindModules.LookupValue((UPTR)targetModule, targetModule) !=
- LPVOID(INVALIDENTRY))
- {
- return FALSE;
- }
-
- if (m_hardBoundModules.LookupValue((UPTR)targetModule, targetModule) !=
- LPVOID(INVALIDENTRY))
- {
- return TRUE;
- }
-
- const char * logMsg = NULL;
-
- EEConfig::NgenHardBindType ngenHardBindConfig = g_pConfig->NgenHardBind();
-
- if (ngenHardBindConfig == EEConfig::NGEN_HARD_BIND_NONE)
- {
- logMsg = "COMPlus_HardPrejitEnabled=0 is specified";
- goto CANNOT_HARD_BIND;
- }
-
- if (ngenHardBindConfig == EEConfig::NGEN_HARD_BIND_ALL)
- {
- // COMPlus_HardPrejitEnabled=2 is specified
- limitToHardBindList = FALSE;
- }
-
- if (!targetModule->HasNativeImage())
- {
- logMsg = "dependency does not have a native image (check FusLogVw for reason)";
- goto CANNOT_HARD_BIND;
- }
-
- // The loader/Fusion cannot currently guarantee that a non-manifest module of a
- // hardbound dependency gets eagerly loaded.
- if (!targetModule->GetFile()->IsAssembly())
- {
- logMsg = "dependency is a non-manifest module";
- goto CANNOT_HARD_BIND;
- }
-
- // Don't hard bind to modules not on the list
- if (limitToHardBindList && m_useHardBindList)
- {
- if (!IsInHardBindRequestList(targetModule->GetAssembly()))
- {
- logMsg = "dependency was not found in m_assemblyHardBindList";
- goto CANNOT_HARD_BIND;
- }
- }
-
- // Mark targetModule as a hard dependency
- //
- m_hardBoundModules.InsertValue((UPTR)targetModule, targetModule);
-
- // Update m_pDependencies for the corresponding assembly, to reflect the fact
- // that we are hard-binding to its native image
- //
- PEAssembly * pTargetAssembly;
- pTargetAssembly = targetModule->GetFile()->GetAssembly();
- UpdateDependencyEntryForHardBind(pTargetAssembly);
-
- logMsg = "new dependency";
-
- // Try to hardbind to the hardbound dependency closure as there is
- // no extra cost in doing so
- IncludeHardBindClosure(pTargetAssembly);
-
- LOG((LF_ZAP, LL_INFO100, "Success CanEagerBindToZapFile: %S (%s)\n",
- targetModule->GetDebugName(), logMsg));
-
- return TRUE;
-
-CANNOT_HARD_BIND:
-
- m_cantHardBindModules.InsertValue((UPTR)targetModule, targetModule);
-
- // If we have a hard binding list, check if this module is on the list.
- if (targetModule->GetFile()->IsAssembly() &&
- IsInHardBindRequestList(targetModule->GetAssembly()))
- {
- StackSString displayName;
- targetModule->GetAssembly()->GetDisplayName(displayName);
-
- GetSvcLogger()->Printf(LogLevel_Warning, W("WARNING: Cannot hardbind to %s because %S\n"),
- displayName.GetUnicode(), logMsg);
- }
-
- if (logMsg)
- {
- LOG((LF_ZAP, LL_INFO100, "Failure CanEagerBindToZapFile: %S (%s)\n",
- targetModule->GetDebugName(), logMsg));
- }
-
- return FALSE;
-#endif // FEATURE_CORECLR
-}
-
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
-
-SArray<LPCWSTR> * s_pPlatformAssembliesPaths;
-
-void ZapperSetPlatformAssembliesPaths(SString &platformAssembliesPaths)
-{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE(s_pPlatformAssembliesPaths == NULL);
- s_pPlatformAssembliesPaths = new SArray<LPCWSTR>();
-
- SString strPaths(platformAssembliesPaths);
- if (strPaths.IsEmpty())
- return;
-
- for (SString::Iterator i = strPaths.Begin(); i != strPaths.End(); )
- {
- // Skip any leading spaces or semicolons
- if (strPaths.Skip(i, W(';')))
- {
- continue;
- }
-
- SString::Iterator iEnd = i; // Where current assembly name ends
- SString::Iterator iNext; // Where next assembly name starts
- if (strPaths.Find(iEnd, W(';')))
- {
- iNext = iEnd + 1;
- }
- else
- {
- iNext = iEnd = strPaths.End();
- }
-
- _ASSERTE(i < iEnd);
- if(i != iEnd)
- {
- SString strPath(strPaths, i, iEnd);
-
- SString strFullPath;
- Clr::Util::Win32::GetFullPathName(strPath, strFullPath, NULL);
-
- NewArrayHolder<WCHAR> wszFullPath = DuplicateStringThrowing(strFullPath.GetUnicode());
- s_pPlatformAssembliesPaths->Append(wszFullPath);
- wszFullPath.SuppressRelease();
- }
- i = iNext;
- }
}
-BOOL CompilationDomain::FindImage(const SString& fileName, MDInternalImportFlags flags, PEImage ** ppImage)
-{
- if (s_pPlatformAssembliesPaths == NULL)
- return FALSE;
-
- for (COUNT_T i = 0; i < s_pPlatformAssembliesPaths->GetCount(); i++)
- {
- SString sPath((*s_pPlatformAssembliesPaths)[i]);
- if (sPath[sPath.GetCount() - 1] != '\\')
- sPath.Append(W("\\"));
- sPath.Append(fileName);
-
- if (!FileExists(sPath))
- continue;
-
- // Normalize the path to maintain identity
- SString sFullPath;
- Clr::Util::Win32::GetFullPathName(sPath, sFullPath, NULL);
-
- PEImageHolder image(PEImage::OpenImage(sFullPath, flags));
-
- PEImageLayoutHolder pLayout(image->GetLayout(
- (flags == MDInternalImport_NoCache) ? PEImageLayout::LAYOUT_FLAT : PEImageLayout::LAYOUT_MAPPED,
- PEImage::LAYOUT_CREATEIFNEEDED));
-
- if (!pLayout->HasNTHeaders())
- continue;
-
- if (!pLayout->IsNativeMachineFormat())
- {
- // Check for platform agnostic IL
- if (!pLayout->IsPlatformNeutral())
- continue;
- }
-
- *ppImage = image.Extract();
- return TRUE;
- }
-
- return FALSE;
-}
-
-BOOL CompilationDomain::IsInHardBindList(SString& simpleName)
-{
- for (COUNT_T i = 0; i < m_assemblyHardBindList.GetCount(); i++)
- {
- if (simpleName.Equals(m_assemblyHardBindList[i]))
- return TRUE;
- }
-
- return FALSE;
-}
-
-void CompilationDomain::ComputeAssemblyHardBindList(IMDInternalImport * pImport)
-{
- AssemblyForLoadHint assembly(pImport);
-
- HENUMInternalHolder hEnum(pImport);
- hEnum.EnumAllInit(mdtAssemblyRef);
-
- mdAssembly token;
- while (pImport->EnumNext(&hEnum, &token))
- {
- LPCSTR pszName;
- IfFailThrow(pImport->GetAssemblyRefProps(token, NULL, NULL,
- &pszName, NULL,
- NULL, NULL, NULL));
-
- SString sSimpleName(SString::Utf8, pszName);
-
- SString sFileName(sSimpleName, W(".dll"));
-
- PEImageHolder pDependencyImage;
-
- if (!FindImage(sFileName, MDInternalImport_Default, &pDependencyImage))
- continue;
-
- AssemblyForLoadHint assemblyDependency(pDependencyImage->GetMDImport());
-
- LoadHintEnum loadHint;
- ::GetLoadHint(&assembly, &assemblyDependency, &loadHint);
-
- if (loadHint == LoadAlways)
- {
- GetSvcLogger()->Printf(W("Hardbinding to %s\n"), sSimpleName.GetUnicode());
-
- if (!IsInHardBindList(sSimpleName))
- {
- m_assemblyHardBindList.Append(sSimpleName);
- }
- }
- }
-
- // Note that we are not setting m_useHardBindList to TRUE here. When we load the NGen image, we are good to hardbind.
- // m_useHardBindList = TRUE;
-}
-#endif
void CompilationDomain::SetTarget(Assembly *pAssembly, Module *pModule)
{
_ASSERTE(pImage->GetModule() == GetTargetModule());
}
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
void ReportMissingDependency(Exception * e)
{
// Avoid duplicate error messages
g_hrFatalError = COR_E_FILELOAD;
}
-#endif
PEAssembly *CompilationDomain::BindAssemblySpec(
AssemblySpec *pSpec,
}
EX_HOOK
{
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
if (!g_fNGenMissingDependenciesOk)
{
ReportMissingDependency(GET_EXCEPTION());
EX_RETHROW;
}
-#endif
//
// Record missing dependencies
m_pDependencyRefSpecs = new AssemblySpecHash();
}
-#ifndef FEATURE_CORECLR // hardbinding
-/* Update m_pDependencies for the corresponding assembly, to reflect the fact
- that we are hard-binding to its native image
- */
-
-void CompilationDomain::UpdateDependencyEntryForHardBind(PEAssembly * pDependencyAssembly)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(pDependencyAssembly->HasBindableIdentity()); // Currently no hard deps on WinMD files.
- }
- CONTRACTL_END;
- AssemblySpec assemblySpec;
- assemblySpec.InitializeSpec(pDependencyAssembly);
-
- mdAssemblyRef defToken;
- IfFailThrow(assemblySpec.EmitToken(m_pEmit, &defToken));
-
- CORCOMPILE_DEPENDENCY * pDep = m_pDependencies;
-
- for (unsigned i = 0; i < m_cDependenciesCount; i++, pDep++)
- {
- if (pDep->dwAssemblyDef == defToken)
- {
- PEImage * pNativeImage = pDependencyAssembly->GetPersistentNativeImage();
- CORCOMPILE_VERSION_INFO * pNativeVersion = pNativeImage->GetLoadedLayout()->GetNativeVersionInfo();
- _ASSERTE(pDep->signNativeImage == INVALID_NGEN_SIGNATURE ||
- pDep->signNativeImage == pNativeVersion->signature);
- pDep->signNativeImage = pNativeVersion->signature;
- return;
- }
- }
-
- // We should have found and updated the corresponding dependency
- _ASSERTE(!"This should be unreachable");
-}
-
-// pAssembly is a hardbound ngen dependency of m_pTargetModule.
-// Try to hardbind to the hardbound dependency closure as there is
-// no extra cost in doing so, and it will help generate better code
-//
-
-void CompilationDomain::IncludeHardBindClosure(PEAssembly * pAssembly)
-{
- CONTRACTL {
- PRECONDITION(pAssembly->GetPersistentNativeImage() != NULL);
- } CONTRACTL_END;
-
- PEImageLayout *pNativeImage = pAssembly->GetLoadedNative();
- COUNT_T cDependencies;
- CORCOMPILE_DEPENDENCY *pDependencies = pNativeImage->GetNativeDependencies(&cDependencies);
- CORCOMPILE_DEPENDENCY *pDependenciesEnd = pDependencies + cDependencies;
-
- for (/**/; pDependencies < pDependenciesEnd; pDependencies++)
- {
- // Ignore "soft" dependencies
-
- if (pDependencies->signNativeImage == INVALID_NGEN_SIGNATURE)
- continue;
-
- // Load the manifest file for the given hardbound name-assembly-spec.
-
- AssemblySpec name;
- name.InitializeSpec(pDependencies->dwAssemblyRef,
- pAssembly->GetPersistentNativeImage()->GetNativeMDImport(),
- FindAssembly(pAssembly),
- FALSE);
-
- DomainAssembly * pDependency = name.LoadDomainAssembly(FILE_LOADED);
-
- // Since pAssembly hardbinds to pDependency, pDependency better
- // have a native image
- _ASSERTE(pDependency->GetFile()->HasNativeImage());
-
- //
- // Now add pDependency as a hard dependency of m_pTargetModule.
- // We pass in limitToHardBindList=FALSE as it is OK to hardbind even if
- // pDependency is not in the hardbound list.
- //
-
- CanEagerBindToZapFile(pDependency->GetLoadedModule(), FALSE);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Check if we were successfully able to hardbind to the requested dependency
-
-void CompilationDomain::CheckHardBindToZapFile(SString dependencyNameFromCA)
-{
- // First check if we were successfully able to hard-bind
-
- for (PtrHashMap::PtrIterator hbItr = m_hardBoundModules.begin(); !hbItr.end(); ++hbItr)
- {
- Module * pModule = (Module*) hbItr.GetValue();
-
- if (IsAssemblySpecifiedInCA(pModule->GetAssembly(), dependencyNameFromCA))
- {
- // We did successfully use "dependencyNameFromCA"
- return;
- }
- }
-
- // Next, check if we failed to hard-bind. CompilationDomain::CanEagerBindToZapFile()
- // would have logged a warning message with the cause of the soft-bind
-
- for (PtrHashMap::PtrIterator sbItr = m_cantHardBindModules.begin(); !sbItr.end(); ++sbItr)
- {
- Module * pModule = (Module*) sbItr.GetValue();
-
- if (IsAssemblySpecifiedInCA(pModule->GetAssembly(), dependencyNameFromCA))
- {
- if (!IsInHardBindRequestList(pModule->GetAssembly()))
- {
- // CompilationDomain::CanEagerBindToZapFile() does not give a warning
- // message for the cyclic dependency case, since the NGEN service
- // breaks the cycle by overriding the CA. So give a message here instead.
- GetSvcLogger()->Printf(LogLevel_Warning, W("WARNING: Dependency attribute for %s is being ignored, possibly because of cyclic dependencies.\n"),
- dependencyNameFromCA.GetUnicode());
- }
- return;
- }
- }
-
- // Finally, it looks like the assembly was either not loaded, or that
- // there was no reason to even try to hard-bind.
-
- GetSvcLogger()->Printf(LogLevel_Warning, W("WARNING: Cannot hardbind to %s because it is not loaded\n"),
- dependencyNameFromCA.GetUnicode());
-}
-
-//-----------------------------------------------------------------------------
-// Check if we were successfully able to hardbind to all the requested
-// dependencies.
-
-void CompilationDomain::CheckLoadHints()
-{
- if (!m_useHardBindList)
- return;
-
- if (g_pConfig->NgenHardBind() == EEConfig::NGEN_HARD_BIND_NONE)
- return;
-
- // Look for the binding custom attribute
-
- IMDInternalImport * pImport = m_pTargetAssembly->GetManifestImport();
- _ASSERTE(pImport);
-
- MDEnumHolder hEnum(pImport); // Enumerator for custom attributes
- if (FAILED(pImport->EnumCustomAttributeByNameInit(m_pTargetAssembly->GetManifestToken(),
- DEPENDENCY_TYPE,
- &hEnum)))
- {
- return;
- }
-
- mdCustomAttribute tkAttribute; // A custom attribute on this assembly.
- const BYTE *pbAttr; // Custom attribute data as a BYTE*.
- ULONG cbAttr; // Size of custom attribute data.
-
- while (pImport->EnumNext(&hEnum, &tkAttribute))
- { // Get raw custom attribute.
- IfFailThrow(pImport->GetCustomAttributeAsBlob(tkAttribute, (const void**)&pbAttr, &cbAttr));
-
- CustomAttributeParser cap(pbAttr, cbAttr);
- if (FAILED(cap.ValidateProlog()))
- {
- THROW_BAD_FORMAT(BFA_BAD_CA_HEADER, m_pTargetAssembly->GetManifestModule());
- }
-
- LPCUTF8 szString;
- ULONG cbString;
- if (FAILED(cap.GetNonNullString(&szString, &cbString)))
- {
- THROW_BAD_FORMAT(BFA_BAD_CA_STRING, m_pTargetAssembly->GetManifestModule());
- }
-
- UINT32 u4;
- IfFailThrow(cap.GetU4(&u4));
- LoadHintEnum loadHint = (LoadHintEnum)u4;
-
- if (loadHint != LoadAlways)
- continue;
-
- // Convert the string to Unicode.
- StackSString dependencyNameFromCA(SString::Utf8, szString, cbString);
-
- CheckHardBindToZapFile(dependencyNameFromCA);
- }
-}
-#endif // FEATURE_CORECLR
HRESULT
CompilationDomain::GetDependencies(CORCOMPILE_DEPENDENCY **ppDependencies,
{
STANDARD_VM_CONTRACT;
-#ifndef FEATURE_CORECLR // hardbinding
- CheckLoadHints();
-#endif
//
// Return the bindings.
}
#endif // CROSSGEN_COMPILE
-#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR)
-bool UseRyuJit()
-{
-#ifdef CROSSGEN_COMPILE
- return true;
-#else
- static ConfigDWORD useRyuJitValue;
- return useRyuJitValue.val(CLRConfig::INTERNAL_UseRyuJit) == 1 || IsNgenOffline();
-#endif
-}
-#endif
#endif // FEATURE_PREJIT
mdFile file,
CORINFO_MODULE_HANDLE *pHandle);
-#ifndef FEATURE_CORECLR
- // Check if the assembly supports automatic NGen
- BOOL SupportsAutoNGen(CORINFO_ASSEMBLY_HANDLE assembly);
-
- HRESULT SetCachedSigningLevel(HANDLE hNI, HANDLE *pModules, COUNT_T nModules);
-#endif
BOOL CheckAssemblyZap(
CORINFO_ASSEMBLY_HANDLE assembly,
class CompilationDomain : public AppDomain,
public ICorCompilationDomain
{
-#ifndef FEATURE_CORECLR
- VPTR_MULTI_VTABLE_CLASS(CompilationDomain, AppDomain);
-#endif
public:
BOOL m_fForceDebug;
HRESULT AddDependencyEntry(PEAssembly *pFile, mdAssemblyRef ref,mdAssemblyRef def);
void ReleaseDependencyEmitter();
-#ifndef FEATURE_CORECLR // hardbinding
- PtrHashMap m_hardBoundModules; // Hard dependency on native image of these dependency modules
- PtrHashMap m_cantHardBindModules;
- void UpdateDependencyEntryForHardBind(PEAssembly * pDependencyAssembly);
- void IncludeHardBindClosure(PEAssembly * pDependencyAssembly);
- void CheckHardBindToZapFile(SString dependencyNameFromCustomAttribute);
- void CheckLoadHints();
-#endif
public:
BOOL CanEagerBindToZapFile(Module *targetModule, BOOL limitToHardBindList = TRUE);
-#ifndef FEATURE_CORECLR // hardbinding
- PtrHashMap::PtrIterator IterateHardBoundModules();
-
- // List of full display names of assemblies to hard-bind to
- SArray<SString,FALSE> m_assemblyHardBindList;
- BOOL m_useHardBindList;
- BOOL IsInHardBindRequestList(Assembly * pAssembly);
- BOOL IsInHardBindRequestList(PEAssembly * pAssembly);
- BOOL IsSafeToHardBindTo(PEAssembly * pAssembly);
- void SetAssemblyHardBindList(
- __in_ecount( cHardBindList )
- LPWSTR *pHardBindList,
- DWORD cHardBindList);
-#endif
-
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- void ComputeAssemblyHardBindList(IMDInternalImport * pImport);
- BOOL IsInHardBindList(SString& simpleName);
-
- static BOOL FindImage(const SString& fileName, MDInternalImportFlags flags, PEImage ** ppImage);
-#endif
// Returns NULL on out-of-memory
RefCache *GetRefCache(Module *pModule)
}
FCIMPLEND
-#ifndef FEATURE_CORECLR
-// You can only suspend a running thread.
-FCIMPL1(void, ThreadNative::Suspend, ThreadBaseObject* pThisUNSAFE)
-{
- FCALL_CONTRACT;
-
- if (pThisUNSAFE == NULL)
- FCThrowResVoid(kNullReferenceException, W("NullReference_This"));
-
- Thread *thread = pThisUNSAFE->GetInternal();
-
- HELPER_METHOD_FRAME_BEGIN_0();
-
-#ifdef MDA_SUPPORTED
- MDA_TRIGGER_ASSISTANT(DangerousThreadingAPI, ReportViolation(W("System.Threading.Thread.Suspend")));
-#endif
-
- if (!ThreadIsRunning(thread))
- COMPlusThrow(kThreadStateException, IDS_EE_THREAD_SUSPEND_NON_RUNNING);
-
- thread->UserSuspendThread();
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-// You can only resume a thread that is in the user-suspended state. (This puts a large
-// burden on the app developer, but we want him to be thinking carefully about race
-// conditions. Precise errors give him a hope of sorting out his logic).
-FCIMPL1(void, ThreadNative::Resume, ThreadBaseObject* pThisUNSAFE)
-{
- FCALL_CONTRACT;
-
- if (pThisUNSAFE == NULL)
- FCThrowResVoid(kNullReferenceException, W("NullReference_This"));
-
- Thread *thread = pThisUNSAFE->GetInternal();
-
- HELPER_METHOD_FRAME_BEGIN_0();
-
- // UserResumeThread() will return 0 if there isn't a user suspension for us to
- // clear.
- if (!ThreadIsRunning(thread))
- COMPlusThrow(kThreadStateException, IDS_EE_THREAD_RESUME_NON_RUNNING);
-
- if (thread->UserResumeThread() == 0)
- COMPlusThrow(kThreadStateException, IDS_EE_THREAD_RESUME_NON_USER_SUSPEND);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-#endif // FEATURE_CORECLR
// Note that you can manipulate the priority of a thread that hasn't started yet,
// or one that is running. But you get an exception if you manipulate the priority
return (UINT64)reserve;
}
-#ifndef FEATURE_CORECLR
-FCIMPL0(void, ThreadNative::BeginCriticalRegion)
-{
- FCALL_CONTRACT;
- if (CLRHosted())
- {
- GetThread()->BeginCriticalRegion_NoCheck();
- }
-}
-FCIMPLEND
-
-FCIMPL0(void, ThreadNative::EndCriticalRegion)
-{
- FCALL_CONTRACT;
- if (CLRHosted())
- {
- GetThread()->EndCriticalRegion_NoCheck();
- }
-}
-FCIMPLEND
-
-FCIMPL0(void, ThreadNative::BeginThreadAffinity)
-{
- FCALL_CONTRACT;
- Thread::BeginThreadAffinity();
-}
-FCIMPLEND
-
-FCIMPL0(void, ThreadNative::EndThreadAffinity)
-{
- FCALL_CONTRACT;
- Thread::EndThreadAffinity();
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
FCIMPL1(FC_BOOL_RET, ThreadNative::IsThreadpoolThread, ThreadBaseObject* thread)
}
FCIMPLEND
-#ifndef FEATURE_CORECLR // core clr does not support abort reason
-FCIMPL1(Object*, ThreadNative::GetAbortReason, ThreadBaseObject *pThisUNSAFE)
-{
- FCALL_CONTRACT;
-
- if (pThisUNSAFE==NULL)
- FCThrowRes(kNullReferenceException, W("NullReference_This"));
-
- OBJECTREF refRetVal = NULL;
- Thread *pThread = pThisUNSAFE->GetInternal();
-
- // Set up a frame in case of GC or EH
- HELPER_METHOD_FRAME_BEGIN_RET_1(refRetVal)
-
- if (pThread == NULL)
- COMPlusThrow(kThreadStateException, IDS_EE_THREAD_CANNOT_GET);
-
- // While the ExceptionInfo probably will be *set* from a different
- // thread, it should only be *read* from the current thread.
- _ASSERTE(GetThread() == pThread);
-
- // Set cooperative mode, to avoid AD unload while we're working.
- GCX_COOP();
-
- OBJECTHANDLE oh=NULL;
- ADID adid;
- // Scope the lock to reading the two fields on the Thread object.
- { // Atomically get the OBJECTHANDLE and ADID of the object
- // NOTE: get the lock on this thread object, not on the executing thread.
- Thread::AbortRequestLockHolder lock(pThread);
- oh = pThread->m_AbortReason;
- adid = pThread->m_AbortReasonDomainID;
- }
-
- // If the OBJECTHANDLE is not 0...
- if (oh != 0)
- {
-
- AppDomain *pCurrentDomain = pThread->GetDomain();
- // See if the appdomain is equal to the appdomain of the currently running
- // thread.
-
- if (pCurrentDomain->GetId() == adid)
- { // Same appdomain; just return object from the OBJECTHANDLE
- refRetVal = ObjectFromHandle(oh);
- }
- else
- { // Otherwise, try to marshal the object from the other AppDomain
- ENTER_DOMAIN_ID(adid);
- CrossAppDomainClonerCallback cadcc;
- ObjectClone Cloner(&cadcc, CrossAppDomain, FALSE);
- refRetVal = Cloner.Clone(ObjectFromHandle(oh), GetAppDomain(), pCurrentDomain, NULL);
- Cloner.RemoveGCFrames();
- END_DOMAIN_TRANSITION;
- }
- }
-
- HELPER_METHOD_FRAME_END()
-
- return OBJECTREFToObject(refRetVal);
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
FCIMPL1(void, ThreadNative::ClearAbortReason, ThreadBaseObject* pThisUNSAFE)
{
static FCDECL1(void, Abort, ThreadBaseObject* pThis);
static FCDECL1(void, ResetAbort, ThreadBaseObject* pThis);
static FCDECL2(void, Start, ThreadBaseObject* pThisUNSAFE, StackCrawlMark* pStackMark);
-#ifndef FEATURE_CORECLR
- static FCDECL1(void, Suspend, ThreadBaseObject* pThisUNSAFE);
- static FCDECL1(void, Resume, ThreadBaseObject* pThisUNSAFE);
-#endif // FEATURE_CORECLR
static FCDECL1(INT32, GetPriority, ThreadBaseObject* pThisUNSAFE);
static FCDECL2(void, SetPriority, ThreadBaseObject* pThisUNSAFE, INT32 iPriority);
static FCDECL1(void, Interrupt, ThreadBaseObject* pThisUNSAFE);
UINT64 QCALLTYPE GetProcessDefaultStackSize();
static FCDECL1(INT32, GetManagedThreadId, ThreadBaseObject* th);
-#ifndef FEATURE_CORECLR
- static FCDECL0(void, BeginCriticalRegion);
- static FCDECL0(void, EndCriticalRegion);
- static FCDECL0(void, BeginThreadAffinity);
- static FCDECL0(void, EndThreadAffinity);
-#endif // !FEATURE_CORECLR
static FCDECL1(void, SpinWait, int iterations);
static BOOL QCALLTYPE YieldThread();
static FCDECL0(Object*, GetCurrentThread);
static FCDECL1(void, SetIsThreadStaticsArray, Object* pObject);
static FCDECL2(void, SetAbortReason, ThreadBaseObject* pThisUNSAFE, Object* pObject);
-#ifndef FEATURE_CORECLR
- static FCDECL1(Object*, GetAbortReason, ThreadBaseObject* pThisUNSAFE);
-#endif
static FCDECL1(void, ClearAbortReason, ThreadBaseObject* pThisUNSAFE);
private:
STATIC_CONTRACT_MODE_ANY;
STATIC_CONTRACT_SO_TOLERANT;
-#ifndef FEATURE_CORECLR
- ASYNCRESULTREF asyncResult = overlapped->m_asyncResult;
- // only filestream is expected to have a null delegate in which
- // case we do the necessary book-keeping here. However, for robustness
- // we should make sure that the asyncResult is indeed an instance of
- // FileStreamAsyncResult
- if (asyncResult->GetMethodTable() == g_pAsyncFileStream_AsyncResultClass)
- {
- // Handle reading from & writing to closed pipes. It's possible for
- // an async read on a pipe to be issued and then the pipe is closed,
- // returning this error. This may very well be necessary. -BG
- if (dwErrorCode == ERROR_BROKEN_PIPE || dwErrorCode == ERROR_NO_DATA)
- dwErrorCode = 0;
- asyncResult->SetErrorCode(dwErrorCode);
- asyncResult->SetNumBytes(dwNumBytes);
- asyncResult->SetCompletedAsynchronously();
- asyncResult->SetIsComplete();
-
- // Signal the event - the OS does not do this for us.
- WAITHANDLEREF waitHandle = asyncResult->GetWaitHandle();
- HANDLE h = waitHandle->GetWaitHandle();
- if ((h != NULL) && (h != (HANDLE) -1))
- UnsafeSetEvent(h);
- }
-#endif // !FEATURE_CORECLR
}
VOID BindIoCompletionCallBack_Worker(LPVOID args)
// no user delegate to callback
_ASSERTE((overlapped->m_iocbHelper == NULL) || !"This is benign, but should be optimized");
-#ifndef FEATURE_CORECLR
- // we cannot do this at threadpool initialization time since mscorlib may not have been loaded
- if (!g_pAsyncFileStream_AsyncResultClass)
- {
- g_pAsyncFileStream_AsyncResultClass = MscorlibBinder::GetClass(CLASS__FILESTREAM_ASYNCRESULT);
- }
-#endif // !FEATURE_CORECLR
SetAsyncResultProperties(overlapped, ErrorCode, numBytesTransferred);
}
}
FCIMPLEND
-#ifndef FEATURE_CORECLR
-
-FCIMPL3(StringObject *, ExceptionNative::StripFileInfo, Object *orefExcepUNSAFE, StringObject *orefStrUNSAFE, CLR_BOOL isRemoteStackTrace)
-{
- FCALL_CONTRACT;
-
- OBJECTREF orefExcep = ObjectToOBJECTREF(orefExcepUNSAFE);
- STRINGREF orefStr = (STRINGREF)ObjectToOBJECTREF(orefStrUNSAFE);
-
- if (orefStr == NULL)
- {
- return NULL;
- }
-
- HELPER_METHOD_FRAME_BEGIN_RET_2(orefExcep, orefStr);
-
- if (isRemoteStackTrace)
- {
- if (!AppX::IsAppXProcess() && ExceptionTypeOverridesStackTraceGetter(orefExcep->GetMethodTable()))
- {
- // In classic processes, the remote stack trace could have been generated using a custom get_StackTrace
- // override which means that we would not be able to parse is - strip the whole string by returning NULL.
- orefStr = NULL;
- }
- }
-
- if (orefStr != NULL)
- {
- SString stackTrace;
- orefStr->GetSString(stackTrace);
-
- StripFileInfoFromStackTrace(stackTrace);
-
- orefStr = AllocateString(stackTrace);
- }
-
- HELPER_METHOD_FRAME_END();
- return (StringObject *)OBJECTREFToObject(orefStr);
-}
-FCIMPLEND
-
-#endif // !FEATURE_CORECLR
#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
// This FCall sets a flag against the thread exception state to indicate to
}
FCIMPLEND
-#ifndef FEATURE_CORECLR
-FCIMPL1(OBJECTHANDLE, SizedRefHandle::Initialize, Object* _obj)
-{
- FCALL_CONTRACT;
-
- OBJECTHANDLE result = 0;
- OBJECTREF obj(_obj);
-
- HELPER_METHOD_FRAME_BEGIN_RET_0();
-
- result = GetAppDomain()->CreateSizedRefHandle(obj);
-
- HELPER_METHOD_FRAME_END();
-
- return result;
-}
-FCIMPLEND
-
-FCIMPL1(VOID, SizedRefHandle::Free, OBJECTHANDLE handle)
-{
- FCALL_CONTRACT;
-
- _ASSERTE(handle != NULL);
-
- HELPER_METHOD_FRAME_BEGIN_0();
-
- DestroySizedRefHandle(handle);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-FCIMPL1(LPVOID, SizedRefHandle::GetTarget, OBJECTHANDLE handle)
-{
- FCALL_CONTRACT;
-
- _ASSERTE(handle != NULL);
-
- OBJECTREF objRef = NULL;
-
- objRef = ObjectFromHandle(handle);
-
- FCUnique(0x33);
- return *((LPVOID*)&objRef);
-}
-FCIMPLEND
-
-FCIMPL1(INT64, SizedRefHandle::GetApproximateSize, OBJECTHANDLE handle)
-{
- FCALL_CONTRACT;
-
- _ASSERTE(handle != NULL);
-
- return (INT64)HndGetHandleExtraInfo(handle);
-}
-FCIMPLEND
-#endif //!FEATURE_CORECLR
-#ifdef FEATURE_CORECLR
COMNlsHashProvider COMNlsHashProvider::s_NlsHashProvider;
-#endif // FEATURE_CORECLR
COMNlsHashProvider::COMNlsHashProvider()
#include "windows.h"
#undef GetCurrentTime
-#ifndef FEATURE_CORECLR
-#include <winnls.h>
-#endif
#ifdef FEATURE_RANDOMIZED_STRING_HASHING
#pragma warning(push)
static FCDECL1(INT32, GetHashCodeOfPtr, LPVOID ptr);
};
-#ifndef FEATURE_CORECLR
-class SizedRefHandle
-{
-public:
- static FCDECL1(OBJECTHANDLE, Initialize, Object* _obj);
- static FCDECL1(VOID, Free, OBJECTHANDLE handle);
- static FCDECL1(LPVOID, GetTarget, OBJECTHANDLE handle);
- static FCDECL1(INT64, GetApproximateSize, OBJECTHANDLE handle);
-};
-
-typedef BOOL (*PFN_IS_NLS_DEFINED_STRING)(NLS_FUNCTION, DWORD, LPNLSVERSIONINFO, LPCWSTR, INT);
-typedef INT (*PFN_COMPARE_STRING_EX)(LPCWSTR, DWORD, LPCWSTR, INT, LPCWSTR, INT, LPNLSVERSIONINFO, LPVOID, LPARAM);
-typedef INT (*PFN_LC_MAP_STRING_EX)(LPCWSTR, DWORD, LPCWSTR, INT, LPWSTR, INT, LPNLSVERSIONINFO, LPVOID, LPARAM);
-typedef INT (*PFN_FIND_NLS_STRING_EX)(LPCWSTR, DWORD, LPCWSTR, INT, LPCWSTR, INT, LPINT, LPNLSVERSIONINFO, LPVOID, LPARAM);
-typedef INT (*PFN_COMPARE_STRING_ORDINAL)(LPCWSTR, INT, LPCWSTR, INT, BOOL);
-typedef BOOL (*PFN_GET_NLS_VERSION_EX)(NLS_FUNCTION, LPCWSTR, LPNLSVERSIONINFOEX);
-typedef INT (*PFN_FIND_STRING_ORDINAL)(DWORD, LPCWSTR, INT, LPCWSTR, INT, BOOL);
-
-class COMNlsCustomSortLibrary {
-public:
- PFN_IS_NLS_DEFINED_STRING pIsNLSDefinedString;
- PFN_COMPARE_STRING_EX pCompareStringEx;
- PFN_LC_MAP_STRING_EX pLCMapStringEx;
- PFN_FIND_NLS_STRING_EX pFindNLSStringEx;
- PFN_COMPARE_STRING_ORDINAL pCompareStringOrdinal;
- PFN_GET_NLS_VERSION_EX pGetNLSVersionEx;
- PFN_FIND_STRING_ORDINAL pFindStringOrdinal;
-};
-#endif //!FEATURE_CORECLR
typedef const BYTE * PCBYTE;
INT32 HashSortKey(PCBYTE pSrc, SIZE_T cbSrc, BOOL forceRandomHashing, INT64 additionalEntropy);
INT32 HashiStringKnownLower80(LPCWSTR lpszStr, INT32 strLen, BOOL forceRandomHashing, INT64 additionalEntropy);
-#ifdef FEATURE_CORECLR
static COMNlsHashProvider s_NlsHashProvider;
-#endif // FEATURE_CORECLR
#ifdef FEATURE_RANDOMIZED_STRING_HASHING
void SetUseRandomHashing(BOOL useRandomHashing) { LIMITED_METHOD_CONTRACT; bUseRandomHashing = useRandomHashing; }
Context* defaultContext;
defaultContext = pThread->GetDomain()->GetDefaultContext();
_ASSERTE(defaultContext);
-#ifndef FEATURE_CORECLR
- // DoAppropriateWait calls LeaveRuntime/EnterRuntime which may cause the current
- // fiber to be re-scheduled.
- ThreadAffinityAndCriticalRegionHolder affinityAndCriticalRegionHolder(hasThreadAffinity);
-#endif
SafeHandleHolder shh(&sh);
// Note that SafeHandle is a GC object, and RequestCallback and
// DoAppropriateWait work on an array of handles. Don't pass the address
retVal = res;
-#ifndef FEATURE_CORECLR
- if (res == WAIT_OBJECT_0 && hasThreadAffinity) {
- affinityAndCriticalRegionHolder.SuppressRelease();
- }
- else if(res == WAIT_ABANDONED_0) {
- // WAIT_ABANDONED means the specified object is a mutex object that was not released by the thread
- // that owned the mutex object before the owning thread terminated.
- // Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled.
- _ASSERTE(hasThreadAffinity);
- affinityAndCriticalRegionHolder.SuppressRelease();
- }
-#endif
HELPER_METHOD_FRAME_END();
return retVal;
// on CoreCLR we won't break anyone.
// Perhaps in a future release we can fix this, if we aren't quite so concerned about
// compatibility....
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
- if (waitForAll && numWaiters > 1 && pThread->GetApartment() == Thread::AS_InSTA) {
- COMPlusThrow(kNotSupportedException, W("NotSupported_WaitAllSTAThread"));
- }
-#endif // FEATURE_COMINTEROP && !FEATURE_CORECLR
WaitHandleArrayHolder arrayHolder;
arrayHolder.Initialize(numWaiters, (PTRARRAYREF*) &waitObjects);
pWaitObjects = (PTRARRAYREF)waitObjects; // array of objects on which to wait
HANDLE* internalHandles = (HANDLE*) _alloca(numWaiters*sizeof(HANDLE));
-#ifndef FEATURE_CORECLR
- BOOL *hasThreadAffinity = (BOOL*) _alloca(numWaiters*sizeof(BOOL));
-
- BOOL mayRequireThreadAffinity = FALSE;
-#endif // !FEATURE_CORECLR
for (int i=0;i<numWaiters;i++)
{
WAITHANDLEREF waitObject = (WAITHANDLEREF) pWaitObjects->m_Array[i];
// this behavior seems wrong but someone explicitly coded that condition so it must have been for a reason.
internalHandles[i] = waitObject->m_handle;
-#ifndef FEATURE_CORECLR
- // m_hasThreadAffinity is set for Mutex only
- hasThreadAffinity[i] = waitObject->m_hasThreadAffinity;
- if (hasThreadAffinity[i]) {
- mayRequireThreadAffinity = TRUE;
- }
-#endif // !FEATURE_CORECLR
}
DWORD res = (DWORD) -1;
-#ifndef FEATURE_CORECLR
- ThreadAffinityHolder affinityHolder(mayRequireThreadAffinity);
-#endif // !FEATURE_CORECLR
Context* targetContext;
targetContext = pThread->GetContext();
_ASSERTE(targetContext);
}
}
-#ifndef FEATURE_CORECLR
- if (mayRequireThreadAffinity) {
- if (waitForAll) {
- if (res >= (DWORD) WAIT_OBJECT_0 && res < (DWORD) WAIT_OBJECT_0 + numWaiters) {
- for (int i = 0; i < numWaiters; i ++) {
- if (hasThreadAffinity[i]) {
- Thread::BeginThreadAffinityAndCriticalRegion();
- }
- }
- }
- // If some mutex is abandoned
- else if (res >= (DWORD) WAIT_ABANDONED_0 && res < (DWORD) WAIT_ABANDONED_0+numWaiters) {
- for (int i = 0; i < numWaiters; i ++) {
- if (hasThreadAffinity[i])
- {
- if (WaitForSingleObject(internalHandles[i],0) == WAIT_OBJECT_0)
- {
- BOOL result;
- result = ReleaseMutex(internalHandles[i]);
- _ASSERTE (result);
- Thread::BeginThreadAffinityAndCriticalRegion();
- }
- }
- }
- }
- }
- else {
- if ( res >= (DWORD)WAIT_OBJECT_0 && res < (DWORD)WAIT_OBJECT_0 + numWaiters) {
- if (hasThreadAffinity[res - WAIT_OBJECT_0]) {
- Thread::BeginThreadAffinityAndCriticalRegion();
- }
- }
- else if (res >= (DWORD)WAIT_ABANDONED_0 && res < (DWORD)WAIT_ABANDONED_0 + numWaiters) {
- _ASSERTE (hasThreadAffinity[res - WAIT_ABANDONED_0]);
- Thread::BeginThreadAffinityAndCriticalRegion();
- }
- }
- }
-#endif // !FEATURE_CORECLR
retVal = res;
Context* defaultContext = pThread->GetDomain()->GetDefaultContext();
_ASSERTE(defaultContext);
-#ifndef FEATURE_CORECLR
- // DoSignalAndWait calls LeaveRuntime/EnterRuntime which may cause the current
- // fiber to be re-scheduled.
- ThreadAffinityAndCriticalRegionHolder affinityAndCriticalRegionHolder(hasThreadAffinity);
-#endif // !FEATURE_CORECLR
SafeHandleHolder shhSignal(&shSignal);
SafeHandleHolder shhWait(&shWait);
res = pThread->DoSignalAndWait(handles,timeout,TRUE /*alertable*/);
}
-#ifndef FEATURE_CORECLR
- if (res == WAIT_OBJECT_0 && hasThreadAffinity) {
- affinityAndCriticalRegionHolder.SuppressRelease();
- }
- else if(res == WAIT_ABANDONED_0) {
- _ASSERTE(hasThreadAffinity);
- affinityAndCriticalRegionHolder.SuppressRelease();
- }
-#endif // !FEATURE_CORECLR
retVal = res;
result));
}
-#ifndef FEATURE_CORECLR
-
-//
-// Trivial assembly binder for desktop crossgen
-//
-
-VOID AssemblySpec::Bind(AppDomain *pAppDomain,
- BOOL fThrowOnFileNotFound,
- CoreBindResult *pResult,
- BOOL fNgenExplicitBind /* = FALSE */,
- BOOL fExplicitBindToNativeImage /* = FALSE */,
- StackCrawlMark *pCallerStackMark /* = NULL */)
-{
- PEImageHolder pImage;
- BOOL fNativeImage = FALSE;
-
- if (GetCodeBase() != NULL)
- {
- // Normalize the path to maintain identity
- SString sFullAssemblyPath;
- Clr::Util::Win32::GetFullPathName(GetCodeBase(), sFullAssemblyPath, NULL);
-
- pImage = PEImage::OpenImage(sFullAssemblyPath, MDInternalImport_Default);
- }
- else
- {
- SString sSimpleName(SString::Utf8, m_pAssemblyName);
-
- fNativeImage = !IsReadyToRunCompilation() && pAppDomain->ToCompilationDomain()->IsInHardBindList(sSimpleName);
-
- SString sFileName(sSimpleName, fNativeImage ? W(".ni.dll") : W(".dll"));
-
- if (!CompilationDomain::FindImage(sFileName,
- fNativeImage ? MDInternalImport_TrustedNativeImage : MDInternalImport_Default,
- &pImage))
- {
- sFileName.Set(sSimpleName, fNativeImage ? W(".ni.exe") : W(".exe"));
-
- if (!CompilationDomain::FindImage(sFileName,
- fNativeImage ? MDInternalImport_TrustedNativeImage : MDInternalImport_Default,
- &pImage))
- {
- EEFileLoadException::Throw(sSimpleName, COR_E_FILENOTFOUND);
- }
- }
- }
-
- GetSvcLogger()->Printf(W("Loading %s\n"), pImage->GetPath().GetUnicode());
-
- NewHolder<BINDER_SPACE::Assembly> pAssembly;
- pAssembly = new BINDER_SPACE::Assembly();
-
- pAssembly->m_assemblyPath.Set(pImage->GetPath());
-
- if (fNativeImage)
- pAssembly->SetNativePEImage(pImage.Extract());
- else
- pAssembly->SetPEImage(pImage.Extract());
-
- pResult->Init(pAssembly.Extract(), TRUE, TRUE);
-}
-
-VOID AssemblySpec::BindToSystem(BINDER_SPACE::Assembly** ppAssembly)
-{
- PEImageHolder pImage;
- BOOL fNativeImage = FALSE;
-
- _ASSERTE(ppAssembly != nullptr);
-
- if (g_fAllowNativeImages)
- {
- if (CompilationDomain::FindImage(W("mscorlib.ni.dll"), MDInternalImport_TrustedNativeImage, &pImage))
- fNativeImage = TRUE;
- }
-
- if (!fNativeImage)
- {
- if (!CompilationDomain::FindImage(W("mscorlib.dll"), MDInternalImport_Default, &pImage))
- {
- EEFileLoadException::Throw(W("mscorlib.dll"), COR_E_FILENOTFOUND);
- }
- }
-
- GetSvcLogger()->Printf(W("Loading %s\n"), pImage->GetPath().GetUnicode());
-
- NewHolder<BINDER_SPACE::Assembly> pAssembly;
- pAssembly = new BINDER_SPACE::Assembly();
-
- pAssembly->m_assemblyPath.Set(pImage->GetPath());
-
- if (fNativeImage)
- pAssembly->SetNativePEImage(pImage.Extract());
- else
- pAssembly->SetPEImage(pImage.Extract());
-
- *ppAssembly = pAssembly.Extract();
-}
-
-#endif // !FEATURE_CORECLR
#endif // FEATURE_FUSION
#include "ipcmanagerinterface.h"
#endif // FEATURE_IPCMAN
#include "comcallablewrapper.h"
-#include "hostexecutioncontext.h"
#include "invokeutil.h"
#include "appdomain.inl"
#include "vars.hpp"
INT64 g_PauseTime; // Total time in millisecond the CLR has been paused
Volatile<BOOL> g_IsPaused; // True if the runtime is paused (FAS)
CLREventStatic g_ClrResumeEvent; // Event that is fired at FAS Resuming
-#ifndef FEATURE_CORECLR
-CLREventStatic g_PauseCompletedEvent; // Set when Pause has completed its work on another thread.
-#endif
-#if defined(FEATURE_CORECLR)
extern BYTE g_rbTestKeyBuffer[];
-#endif
-
-#if !defined(FEATURE_CORECLR)
-//******************************************************************************
-// <TODO>TODO: ICorThreadpool: Move this into a separate file CorThreadpool.cpp
-// after the move to VBL </TODO>
-//******************************************************************************
-
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorRegisterWaitForSingleObject(PHANDLE phNewWaitObject,
- HANDLE hWaitObject,
- WAITORTIMERCALLBACK Callback,
- PVOID Context,
- ULONG timeout,
- BOOL executeOnlyOnce,
- BOOL* pResult)
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
- HRESULT hr = E_UNEXPECTED;
+//***************************************************************************
- BEGIN_ENTRYPOINT_NOTHROW;
+ULONG CorRuntimeHostBase::m_Version = 0;
- ULONG flag = executeOnlyOnce ? WAIT_SINGLE_EXECUTION : 0;
- *pResult = FALSE;
- EX_TRY
- {
- *pResult = ThreadpoolMgr::RegisterWaitForSingleObject(phNewWaitObject,
- hWaitObject,
- Callback,
- Context,
- timeout,
- flag);
+#ifdef FEATURE_INCLUDE_ALL_INTERFACES
+static CCLRDebugManager s_CLRDebugManager;
+#endif // FEATURE_INCLUDE_ALL_INTERFACES
- hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError());
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
+#if defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
+CCLRErrorReportingManager g_CLRErrorReportingManager;
+#endif // defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
- END_ENTRYPOINT_NOTHROW;
+#ifdef FEATURE_IPCMAN
+static CCLRSecurityAttributeManager s_CLRSecurityAttributeManager;
+#endif // FEATURE_IPCMAN
- return hr;
-}
+#endif // !DAC
+typedef DPTR(CONNID) PTR_CONNID;
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorBindIoCompletionCallback(HANDLE fileHandle,
- LPOVERLAPPED_COMPLETION_ROUTINE callback)
+#ifdef FEATURE_INCLUDE_ALL_INTERFACES
+// Hash table to keep track <connection, name> for SQL fiber support
+class ConnectionNameTable : CHashTableAndData<CNewDataNoThrow>
{
- CONTRACTL
+ friend class CCLRDebugManager;
+public:
+
+ // Key to match is connection ID.
+ // Returns true if the given HASHENTRY has the same key as the requested key.
+ BOOL Cmp(SIZE_T requestedKey, const HASHENTRY * pEntry)
{
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
+ SUPPORTS_DAC;
+ LIMITED_METHOD_CONTRACT;
+ STATIC_CONTRACT_SO_TOLERANT;
+
+ CONNID keyRequested = (CONNID)requestedKey;
+ CONNID keySearch = dac_cast<PTR_ConnectionNameHashEntry>(pEntry)->m_dwConnectionId;
+ return keyRequested != keySearch;
}
- CONTRACTL_END;
- HRESULT hr = E_UNEXPECTED;
- BEGIN_ENTRYPOINT_NOTHROW;
+ // Hash function
+ ULONG Hash(CONNID dwConnectionId)
+ {
+ SUPPORTS_DAC;
+ LIMITED_METHOD_CONTRACT;
+
+ return (ULONG)(dwConnectionId);
+ }
- BOOL ret = FALSE;
- DWORD errCode = 0;
+#ifndef DACCESS_COMPILE
+ // constructor
+ ConnectionNameTable(
+ ULONG iBuckets) : // # of chains we are hashing into.
+ CHashTableAndData<CNewDataNoThrow>(iBuckets)
+ {LIMITED_METHOD_CONTRACT;}
- EX_TRY
+ // destructor
+ ~ConnectionNameTable()
{
- ret = ThreadpoolMgr::BindIoCompletionCallback(fileHandle,callback,0, errCode);
- hr = (ret ? S_OK : HRESULT_FROM_WIN32(errCode));
+ CONTRACTL
+ {
+ if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+ NOTHROW;
+ }
+ CONTRACTL_END;
+ HASHFIND hashFind;
+ ConnectionNameHashEntry *pNameEntry;
+
+ pNameEntry = (ConnectionNameHashEntry *)FindFirstEntry(&hashFind);
+ while (pNameEntry != NULL)
+ {
+ if (pNameEntry->m_pwzName)
+ {
+ delete pNameEntry->m_pwzName;
+ pNameEntry->m_pwzName = NULL;
+ }
+
+ if (pNameEntry->m_CLRTaskCount != 0)
+ {
+ _ASSERTE(pNameEntry->m_ppCLRTaskArray != NULL);
+ for (UINT i = 0; i < pNameEntry->m_CLRTaskCount; i++)
+ {
+ pNameEntry->m_ppCLRTaskArray[i]->Release();
+ }
+ delete [] pNameEntry->m_ppCLRTaskArray;
+ pNameEntry->m_ppCLRTaskArray = NULL;
+ pNameEntry->m_CLRTaskCount = 0;
+ }
+ pNameEntry = (ConnectionNameHashEntry *)FindNextEntry(&hashFind);
+ }
}
- EX_CATCH
+
+ // Add a new connection into hash table.
+ // This function does not throw but return NULL when memory allocation fails.
+ ConnectionNameHashEntry *AddConnection(
+ CONNID dwConnectionId,
+ __in_z WCHAR *pwzName) // We should review this in the future. This API is
+ // public and callable by a host. This SAL annotation
+ // is the best we can do now.
{
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
+ CONTRACTL
+ {
+ GC_NOTRIGGER;
+ NOTHROW;
+ }
+ CONTRACTL_END;
- END_ENTRYPOINT_NOTHROW;
+ ULONG iHash = Hash(dwConnectionId);
- return hr;
-}
+ size_t len = wcslen(pwzName) + 1;
+ WCHAR *pConnName = new (nothrow) WCHAR[len];
+ if (pConnName == NULL)
+ return NULL;
+ ConnectionNameHashEntry *pRecord = (ConnectionNameHashEntry *)Add(iHash);
+ if (pRecord)
+ {
+ pRecord->m_dwConnectionId = dwConnectionId;
+ pRecord->m_pwzName = pConnName;
+ wcsncpy_s(pRecord->m_pwzName, len, pwzName, len);
+ pRecord->m_CLRTaskCount = 0;
+ pRecord->m_ppCLRTaskArray = NULL;
+ }
+ else
+ {
+ if (pConnName)
+ delete [] pConnName;
+ }
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorUnregisterWait(HANDLE hWaitObject,
- HANDLE CompletionEvent,
- BOOL* pResult)
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
+ return pRecord;
}
- CONTRACTL_END;
- HRESULT hr = E_UNEXPECTED;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pResult = FALSE;
- EX_TRY
+ // Delete a hash entry given a connection id
+ void DeleteConnection(CONNID dwConnectionId)
{
+ CONTRACTL
+ {
+ GC_NOTRIGGER;
+ NOTHROW;
+ }
+ CONTRACTL_END;
+
+ ULONG iHash;
+ iHash = Hash(dwConnectionId);
+ ConnectionNameHashEntry * pRecord =
+ reinterpret_cast<ConnectionNameHashEntry *>(Find(iHash, (SIZE_T)dwConnectionId));
+ if (pRecord == NULL)
+ {
+ return;
+ }
- *pResult = ThreadpoolMgr::UnregisterWaitEx(hWaitObject,CompletionEvent);
- hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError());
+ _ASSERTE(pRecord->m_CLRTaskCount == 0 && pRecord->m_ppCLRTaskArray == NULL);
+ if (pRecord->m_pwzName)
+ {
+ delete pRecord->m_pwzName;
+ pRecord->m_pwzName = NULL;
+ }
+ Delete(iHash, (HASHENTRY *)pRecord);
}
- EX_CATCH
+
+ // return NULL if the given connection id cannot be found.
+ ConnectionNameHashEntry *FindConnection(CONNID dwConnectionId)
{
- hr = GET_EXCEPTION()->GetHR();
+ CONTRACTL
+ {
+ GC_NOTRIGGER;
+ NOTHROW;
+ }
+ CONTRACTL_END;
+
+ ULONG iHash;
+ iHash = Hash(dwConnectionId);
+ return reinterpret_cast<ConnectionNameHashEntry *>(Find(iHash, (SIZE_T)dwConnectionId));
}
- EX_END_CATCH(SwallowAllExceptions);
+#endif // !DAC
+};
+#endif //FEATURE_INCLUDE_ALL_INTERFACES
- END_ENTRYPOINT_NOTHROW;
- return hr;
+// Keep track connection id and name
+#ifdef FEATURE_INCLUDE_ALL_INTERFACES
+SPTR_IMPL(ConnectionNameTable, CCLRDebugManager, m_pConnectionNameHash);
+CrstStatic CCLRDebugManager::m_lockConnectionNameTable;
+#endif // FEATURE_INCLUDE_ALL_INTERFACES
-}
+#ifndef DACCESS_COMPILE
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorQueueUserWorkItem(LPTHREAD_START_ROUTINE Function,
- PVOID Context,BOOL executeOnlyOnce,
- BOOL* pResult )
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
- HRESULT hr = E_UNEXPECTED;
- BEGIN_ENTRYPOINT_NOTHROW;
- *pResult = FALSE;
- EX_TRY
- {
- *pResult = ThreadpoolMgr::QueueUserWorkItem(Function,Context,QUEUE_ONLY);
- hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError());
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
+// *** ICorRuntimeHost methods ***
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorCallOrQueueUserWorkItem(LPTHREAD_START_ROUTINE Function,
- PVOID Context,
- BOOL* pResult )
+extern BOOL g_fWeOwnProcess;
+
+CorHost2::CorHost2()
{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
+ LIMITED_METHOD_CONTRACT;
- HRESULT hr = E_UNEXPECTED;
- BEGIN_ENTRYPOINT_NOTHROW;
- *pResult = FALSE;
- EX_TRY
- {
- *pResult = ThreadpoolMgr::QueueUserWorkItem(Function,Context,CALL_OR_QUEUE);
- hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError());
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
- END_ENTRYPOINT_NOTHROW;
- return hr;
+ m_fStarted = FALSE;
+ m_fFirstToLoadCLR = FALSE;
+ m_fAppDomainCreated = FALSE;
}
+static DangerousNonHostedSpinLock lockOnlyOneToInvokeStart;
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorCreateTimer(PHANDLE phNewTimer,
- WAITORTIMERCALLBACK Callback,
- PVOID Parameter,
- DWORD DueTime,
- DWORD Period,
- BOOL* pResult)
+STDMETHODIMP CorHost2::Start()
{
CONTRACTL
{
- DISABLED(NOTHROW);
+ NOTHROW;
GC_TRIGGERS;
- MODE_ANY;
ENTRY_POINT;
- }
- CONTRACTL_END;
+ }CONTRACTL_END;
- HRESULT hr = E_UNEXPECTED;
- BEGIN_ENTRYPOINT_NOTHROW;
+ HRESULT hr;
- *pResult = FALSE;
- EX_TRY
+ BEGIN_ENTRYPOINT_NOTHROW;
+
+ // Ensure that only one thread at a time gets in here
+ DangerousNonHostedSpinLockHolder lockHolder(&lockOnlyOneToInvokeStart);
+
+ // To provide the complete semantic of Start/Stop in context of a given host, we check m_fStarted and let
+ // them invoke the Start only if they have not already. Likewise, they can invoke the Stop method
+ // only if they have invoked Start prior to that.
+ //
+ // This prevents a host from invoking Stop twice and hitting the refCount to zero, when another
+ // host is using the CLR, as CLR instance sharing across hosts is a scenario for CoreCLR.
+
+ if (g_fEEStarted)
{
- *pResult = ThreadpoolMgr::CreateTimerQueueTimer(phNewTimer,Callback,Parameter,DueTime,Period,0);
- hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError());
+ hr = S_OK;
+ // CoreCLR is already running - but was Start already invoked by this host?
+ if (m_fStarted)
+ {
+ // This host had already invoked the Start method - return them an error
+ hr = HOST_E_INVALIDOPERATION;
+ }
+ else
+ {
+ // Increment the global (and dynamic) refCount...
+ FastInterlockIncrement(&m_RefCount);
+
+ // And set our flag that this host has invoked the Start...
+ m_fStarted = TRUE;
+ }
}
- EX_CATCH
+ else
{
- hr = GET_EXCEPTION()->GetHR();
+ // Using managed C++ libraries, its possible that when the runtime is already running,
+ // MC++ will use CorBindToRuntimeEx to make callbacks into specific appdomain of its
+ // choice. Now, CorBindToRuntimeEx results in CorHost2::CreateObject being invoked
+ // that will set runtime hosted flag "g_fHostConfig |= CLRHOSTED".
+ //
+ // For the case when managed code started without CLR hosting and MC++ does a
+ // CorBindToRuntimeEx, setting the CLR hosted flag is incorrect.
+ //
+ // Thus, before we attempt to start the runtime, we save the status of it being
+ // already running or not. Next, if we are able to successfully start the runtime
+ // and ONLY if it was not started earlier will we set the hosted flag below.
+ if (!g_fEEStarted)
+ {
+ g_fHostConfig |= CLRHOSTED;
+ }
+
+ hr = CorRuntimeHostBase::Start();
+ if (SUCCEEDED(hr))
+ {
+ // Set our flag that this host invoked the Start method.
+ m_fStarted = TRUE;
+
+ // And they also loaded the CoreCLR DLL in the memory (for this version).
+ // This is a special flag as the host that has got this flag set will be allowed
+ // to repeatedly invoke Stop method (without corresponding Start method invocations).
+ // This is to support scenarios like that of Office where they need to bring down
+ // the CLR at any cost.
+ //
+ // So, if you want to do that, just make sure you are the first host to load the
+ // specific version of CLR in memory AND start it.
+ m_fFirstToLoadCLR = TRUE;
+ if (FastInterlockIncrement(&m_RefCount) != 1)
+ {
+ }
+ else
+ {
+ if (g_fWeOwnProcess)
+ {
+ // Runtime is started by a managed exe. Bump the ref-count, so that
+ // matching Start/Stop does not stop runtime.
+ FastInterlockIncrement(&m_RefCount);
+ }
+ }
+ }
}
- EX_END_CATCH(SwallowAllExceptions);
END_ENTRYPOINT_NOTHROW;
return hr;
}
-
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorDeleteTimer(HANDLE Timer, HANDLE CompletionEvent, BOOL* pResult)
+// Starts the runtime. This is equivalent to CoInitializeEE();
+HRESULT CorRuntimeHostBase::Start()
{
CONTRACTL
{
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
+ NOTHROW;
+ DISABLED(GC_TRIGGERS);
ENTRY_POINT;
}
CONTRACTL_END;
- HRESULT hr = E_UNEXPECTED;
- BEGIN_ENTRYPOINT_NOTHROW;
+ HRESULT hr = S_OK;
- *pResult = FALSE;
- EX_TRY
- {
- *pResult = ThreadpoolMgr::DeleteTimerQueueTimer(Timer,CompletionEvent);
- hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError());
- }
- EX_CATCH
+ BEGIN_ENTRYPOINT_NOTHROW;
{
- hr = GET_EXCEPTION()->GetHR();
+ m_Started = TRUE;
+#ifdef FEATURE_EVENT_TRACE
+ g_fEEHostedStartup = TRUE;
+#endif // FEATURE_EVENT_TRACE
+ hr = InitializeEE(COINITEE_DEFAULT);
}
- EX_END_CATCH(SwallowAllExceptions);
-
END_ENTRYPOINT_NOTHROW;
+
return hr;
}
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorChangeTimer(HANDLE Timer,
- ULONG DueTime,
- ULONG Period,
- BOOL* pResult)
+
+HRESULT CorHost2::Stop()
{
CONTRACTL
{
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
+ NOTHROW;
+ ENTRY_POINT; // We're bringing the EE down, so no point in probing
+ if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
}
CONTRACTL_END;
-
- HRESULT hr = E_UNEXPECTED;
+ if (!g_fEEStarted)
+ {
+ return E_UNEXPECTED;
+ }
+ HRESULT hr=S_OK;
BEGIN_ENTRYPOINT_NOTHROW;
- *pResult = FALSE;
- EX_TRY
+ // Is this host eligible to invoke the Stop method?
+ if ((!m_fStarted) && (!m_fFirstToLoadCLR))
{
- //CONTRACT_VIOLATION(ThrowsViolation);
- *pResult = ThreadpoolMgr::ChangeTimerQueueTimer(Timer,DueTime,Period);
- hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError());
+ // Well - since this host never invoked Start, it is not eligible to invoke Stop.
+ // Semantically, for such a host, CLR is not available in the process. The only
+ // exception to this condition is the host that first loaded this version of the
+ // CLR and invoked Start method. For details, refer to comments in CorHost2::Start implementation.
+ hr = HOST_E_CLRNOTAVAILABLE;
}
- EX_CATCH
+ else
{
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
+ while (TRUE)
+ {
+ LONG refCount = m_RefCount;
+ if (refCount == 0)
+ {
+ hr = HOST_E_CLRNOTAVAILABLE;
+ break;
+ }
+ else
+ if (FastInterlockCompareExchange(&m_RefCount, refCount - 1, refCount) == refCount)
+ {
+ // Indicate that we have got a Stop for a corresponding Start call from the
+ // Host. Semantically, CoreCLR has stopped for them.
+ m_fStarted = FALSE;
+ if (refCount > 1)
+ {
+ hr=S_FALSE;
+ break;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
END_ENTRYPOINT_NOTHROW;
+
+
return hr;
}
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorSetMaxThreads(DWORD MaxWorkerThreads,
- DWORD MaxIOCompletionThreads)
+HRESULT CorHost2::GetCurrentAppDomainId(DWORD *pdwAppDomainId)
{
CONTRACTL
{
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
+ NOTHROW;
+ GC_NOTRIGGER;
ENTRY_POINT;
}
CONTRACTL_END;
- HRESULT hr = E_UNEXPECTED;
+ // No point going further if the runtime is not running...
+ // We use CanRunManagedCode() instead of IsRuntimeActive() because this allows us
+ // to specify test using the form that does not trigger a GC.
+ if (!(g_fEEStarted && CanRunManagedCode(LoaderLockCheck::None))
+ || !m_fStarted
+ )
+ {
+ return HOST_E_CLRNOTAVAILABLE;
+ }
+
+ HRESULT hr = S_OK;
+
BEGIN_ENTRYPOINT_NOTHROW;
- BOOL result = FALSE;
- EX_TRY
+ if(pdwAppDomainId == NULL)
{
- result = ThreadpoolMgr::SetMaxThreads(MaxWorkerThreads, MaxIOCompletionThreads);
- hr = (result ? S_OK : E_FAIL);
+ hr = E_POINTER;
}
- EX_CATCH
+ else
{
- hr = GET_EXCEPTION()->GetHR();
+ Thread *pThread = GetThread();
+ if (!pThread)
+ {
+ hr = E_UNEXPECTED;
+ }
+ else
+ {
+ *pdwAppDomainId = SystemDomain::GetCurrentDomain()->GetId().m_dwId;
+ }
}
- EX_END_CATCH(SwallowAllExceptions);
END_ENTRYPOINT_NOTHROW;
+
return hr;
}
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorGetMaxThreads(DWORD *MaxWorkerThreads,
- DWORD *MaxIOCompletionThreads)
+HRESULT CorHost2::ExecuteApplication(LPCWSTR pwzAppFullName,
+ DWORD dwManifestPaths,
+ LPCWSTR *ppwzManifestPaths,
+ DWORD dwActivationData,
+ LPCWSTR *ppwzActivationData,
+ int *pReturnValue)
+{
+ return E_NOTIMPL;
+}
+
+/*
+ * This method processes the arguments sent to the host which are then used
+ * to invoke the main method.
+ * Note -
+ * [0] - points to the assemblyName that has been sent by the host.
+ * The rest are the arguments sent to the assembly.
+ * Also note, this might not always return the exact same identity as the cmdLine
+ * used to invoke the method.
+ *
+ * For example :-
+ * ActualCmdLine - Foo arg1 arg2.
+ * (Host1) - Full_path_to_Foo arg1 arg2
+*/
+void SetCommandLineArgs(LPCWSTR pwzAssemblyPath, int argc, LPCWSTR* argv)
{
CONTRACTL
{
- DISABLED(NOTHROW);
+ THROWS;
GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
+ MODE_COOPERATIVE;
}
CONTRACTL_END;
- HRESULT hr = E_UNEXPECTED;
- BEGIN_ENTRYPOINT_NOTHROW;
+ struct _gc
+ {
+ PTRARRAYREF cmdLineArgs;
+ } gc;
- BOOL result = FALSE;
- EX_TRY
+ ZeroMemory(&gc, sizeof(gc));
+ GCPROTECT_BEGIN(gc);
+
+ gc.cmdLineArgs = (PTRARRAYREF)AllocateObjectArray(argc + 1 /* arg[0] should be the exe name*/, g_pStringClass);
+ OBJECTREF orAssemblyPath = StringObject::NewString(pwzAssemblyPath);
+ gc.cmdLineArgs->SetAt(0, orAssemblyPath);
+
+ for (int i = 0; i < argc; ++i)
{
- result = ThreadpoolMgr::GetMaxThreads(MaxWorkerThreads, MaxIOCompletionThreads);
- hr = (result ? S_OK : E_FAIL);
+ OBJECTREF argument = StringObject::NewString(argv[i]);
+ gc.cmdLineArgs->SetAt(i + 1, argument);
}
- EX_CATCH
+
+ MethodDescCallSite setCmdLineArgs(METHOD__ENVIRONMENT__SET_COMMAND_LINE_ARGS);
+
+ ARG_SLOT args[] =
{
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
+ ObjToArgSlot(gc.cmdLineArgs),
+ };
+ setCmdLineArgs.Call(args);
- END_ENTRYPOINT_NOTHROW;
- return hr;
+ GCPROTECT_END();
}
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorGetAvailableThreads(DWORD *AvailableWorkerThreads,
- DWORD *AvailableIOCompletionThreads)
+HRESULT CorHost2::ExecuteAssembly(DWORD dwAppDomainId,
+ LPCWSTR pwzAssemblyPath,
+ int argc,
+ LPCWSTR* argv,
+ DWORD *pReturnValue)
{
CONTRACTL
{
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
+ THROWS; // Throws...as we do not want it to swallow the managed exception
ENTRY_POINT;
}
CONTRACTL_END;
- HRESULT hr = E_UNEXPECTED;
- BEGIN_ENTRYPOINT_NOTHROW;
+ // This is currently supported in default domain only
+ if (dwAppDomainId != DefaultADID)
+ return HOST_E_INVALIDOPERATION;
- BOOL result = FALSE;
- EX_TRY
- {
- result = ThreadpoolMgr::GetAvailableThreads(AvailableWorkerThreads, AvailableIOCompletionThreads);
- hr = (result ? S_OK : E_FAIL);
- }
- EX_CATCH
+ // No point going further if the runtime is not running...
+ if (!IsRuntimeActive() || !m_fStarted)
{
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-#endif // !defined(FEATURE_CORECLR)
-//***************************************************************************
-
-ULONG CorRuntimeHostBase::m_Version = 0;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-static CCLRDebugManager s_CLRDebugManager;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
-CCLRErrorReportingManager g_CLRErrorReportingManager;
-#endif // defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
-
-#ifdef FEATURE_IPCMAN
-static CCLRSecurityAttributeManager s_CLRSecurityAttributeManager;
-#endif // FEATURE_IPCMAN
-
-#endif // !DAC
-
-typedef DPTR(CONNID) PTR_CONNID;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-// Hash table to keep track <connection, name> for SQL fiber support
-class ConnectionNameTable : CHashTableAndData<CNewDataNoThrow>
-{
- friend class CCLRDebugManager;
-public:
+ return HOST_E_CLRNOTAVAILABLE;
+ }
+
+ if(!pwzAssemblyPath)
+ return E_POINTER;
- // Key to match is connection ID.
- // Returns true if the given HASHENTRY has the same key as the requested key.
- BOOL Cmp(SIZE_T requestedKey, const HASHENTRY * pEntry)
+ if(argc < 0)
{
- SUPPORTS_DAC;
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
-
- CONNID keyRequested = (CONNID)requestedKey;
- CONNID keySearch = dac_cast<PTR_ConnectionNameHashEntry>(pEntry)->m_dwConnectionId;
- return keyRequested != keySearch;
+ return E_INVALIDARG;
}
- // Hash function
- ULONG Hash(CONNID dwConnectionId)
+ if(argc > 0 && argv == NULL)
{
- SUPPORTS_DAC;
- LIMITED_METHOD_CONTRACT;
-
- return (ULONG)(dwConnectionId);
+ return E_INVALIDARG;
}
-#ifndef DACCESS_COMPILE
- // constructor
- ConnectionNameTable(
- ULONG iBuckets) : // # of chains we are hashing into.
- CHashTableAndData<CNewDataNoThrow>(iBuckets)
- {LIMITED_METHOD_CONTRACT;}
+ HRESULT hr = S_OK;
- // destructor
- ~ConnectionNameTable()
- {
- CONTRACTL
- {
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- NOTHROW;
- }
- CONTRACTL_END;
- HASHFIND hashFind;
- ConnectionNameHashEntry *pNameEntry;
+ AppDomain *pCurDomain = SystemDomain::GetCurrentDomain();
- pNameEntry = (ConnectionNameHashEntry *)FindFirstEntry(&hashFind);
- while (pNameEntry != NULL)
+ Thread *pThread = GetThread();
+ if (pThread == NULL)
+ {
+ pThread = SetupThreadNoThrow(&hr);
+ if (pThread == NULL)
{
- if (pNameEntry->m_pwzName)
- {
- delete pNameEntry->m_pwzName;
- pNameEntry->m_pwzName = NULL;
- }
-
- if (pNameEntry->m_CLRTaskCount != 0)
- {
- _ASSERTE(pNameEntry->m_ppCLRTaskArray != NULL);
- for (UINT i = 0; i < pNameEntry->m_CLRTaskCount; i++)
- {
- pNameEntry->m_ppCLRTaskArray[i]->Release();
- }
- delete [] pNameEntry->m_ppCLRTaskArray;
- pNameEntry->m_ppCLRTaskArray = NULL;
- pNameEntry->m_CLRTaskCount = 0;
- }
- pNameEntry = (ConnectionNameHashEntry *)FindNextEntry(&hashFind);
+ goto ErrExit;
}
}
- // Add a new connection into hash table.
- // This function does not throw but return NULL when memory allocation fails.
- ConnectionNameHashEntry *AddConnection(
- CONNID dwConnectionId,
- __in_z WCHAR *pwzName) // We should review this in the future. This API is
- // public and callable by a host. This SAL annotation
- // is the best we can do now.
+ if(pCurDomain->GetId().m_dwId != DefaultADID)
{
- CONTRACTL
- {
- GC_NOTRIGGER;
- NOTHROW;
- }
- CONTRACTL_END;
+ return HOST_E_INVALIDOPERATION;
+ }
- ULONG iHash = Hash(dwConnectionId);
+ INSTALL_UNHANDLED_MANAGED_EXCEPTION_TRAP;
+ INSTALL_UNWIND_AND_CONTINUE_HANDLER;
- size_t len = wcslen(pwzName) + 1;
- WCHAR *pConnName = new (nothrow) WCHAR[len];
- if (pConnName == NULL)
- return NULL;
+ _ASSERTE (!pThread->PreemptiveGCDisabled());
- ConnectionNameHashEntry *pRecord = (ConnectionNameHashEntry *)Add(iHash);
- if (pRecord)
- {
- pRecord->m_dwConnectionId = dwConnectionId;
- pRecord->m_pwzName = pConnName;
- wcsncpy_s(pRecord->m_pwzName, len, pwzName, len);
- pRecord->m_CLRTaskCount = 0;
- pRecord->m_ppCLRTaskArray = NULL;
- }
- else
- {
- if (pConnName)
- delete [] pConnName;
- }
+ Assembly *pAssembly = AssemblySpec::LoadAssembly(pwzAssemblyPath);
- return pRecord;
- }
+#if defined(FEATURE_MULTICOREJIT)
+ pCurDomain->GetMulticoreJitManager().AutoStartProfile(pCurDomain);
+#endif // defined(FEATURE_MULTICOREJIT)
- // Delete a hash entry given a connection id
- void DeleteConnection(CONNID dwConnectionId)
{
- CONTRACTL
- {
- GC_NOTRIGGER;
- NOTHROW;
- }
- CONTRACTL_END;
+ GCX_COOP();
- ULONG iHash;
- iHash = Hash(dwConnectionId);
- ConnectionNameHashEntry * pRecord =
- reinterpret_cast<ConnectionNameHashEntry *>(Find(iHash, (SIZE_T)dwConnectionId));
- if (pRecord == NULL)
- {
- return;
- }
+ // Here we call the managed method that gets the cmdLineArgs array.
+ SetCommandLineArgs(pwzAssemblyPath, argc, argv);
- _ASSERTE(pRecord->m_CLRTaskCount == 0 && pRecord->m_ppCLRTaskArray == NULL);
- if (pRecord->m_pwzName)
+ PTRARRAYREF arguments = NULL;
+ GCPROTECT_BEGIN(arguments);
+
+ arguments = (PTRARRAYREF)AllocateObjectArray(argc, g_pStringClass);
+ for (int i = 0; i < argc; ++i)
{
- delete pRecord->m_pwzName;
- pRecord->m_pwzName = NULL;
+ STRINGREF argument = StringObject::NewString(argv[i]);
+ arguments->SetAt(i, argument);
}
- Delete(iHash, (HASHENTRY *)pRecord);
- }
- // return NULL if the given connection id cannot be found.
- ConnectionNameHashEntry *FindConnection(CONNID dwConnectionId)
- {
- CONTRACTL
+ DWORD retval = pAssembly->ExecuteMainMethod(&arguments, TRUE /* waitForOtherThreads */);
+ if (pReturnValue)
{
- GC_NOTRIGGER;
- NOTHROW;
+ *pReturnValue = retval;
}
- CONTRACTL_END;
-
- ULONG iHash;
- iHash = Hash(dwConnectionId);
- return reinterpret_cast<ConnectionNameHashEntry *>(Find(iHash, (SIZE_T)dwConnectionId));
- }
-#endif // !DAC
-};
-#endif //FEATURE_INCLUDE_ALL_INTERFACES
-
-// Keep track connection id and name
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-SPTR_IMPL(ConnectionNameTable, CCLRDebugManager, m_pConnectionNameHash);
-CrstStatic CCLRDebugManager::m_lockConnectionNameTable;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
+ GCPROTECT_END();
-#ifndef DACCESS_COMPILE
+ }
+ UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
+ UNINSTALL_UNHANDLED_MANAGED_EXCEPTION_TRAP;
-#if !defined(FEATURE_CORECLR) // simple hosting
-//*****************************************************************************
-// ICorRuntimeHost
-//*****************************************************************************
-extern BOOL g_singleVersionHosting;
+ErrExit:
-// *** ICorRuntimeHost methods ***
-// Returns an object for configuring the runtime prior to
-// it starting. If the runtime has been initialized this
-// routine returns an error. See ICorConfiguration.
-HRESULT CorHost::GetConfiguration(ICorConfiguration** pConfiguration)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
- HRESULT hr=E_FAIL;
- BEGIN_ENTRYPOINT_NOTHROW;
- if (CorHost::GetHostVersion() != 1)
- {
- hr=HOST_E_INVALIDOPERATION;
- }
- else
- if (!pConfiguration)
- hr= E_POINTER;
- else
- if (!m_Started)
- {
- *pConfiguration = (ICorConfiguration *) this;
- AddRef();
- hr=S_OK;
- }
- END_ENTRYPOINT_NOTHROW;
- // Cannot obtain configuration after the runtime is started
return hr;
}
-STDMETHODIMP CorHost::Start(void)
+HRESULT CorHost2::ExecuteInDefaultAppDomain(LPCWSTR pwzAssemblyPath,
+ LPCWSTR pwzTypeName,
+ LPCWSTR pwzMethodName,
+ LPCWSTR pwzArgument,
+ DWORD *pReturnValue)
{
CONTRACTL
{
NOTHROW;
- GC_TRIGGERS;
ENTRY_POINT;
}
CONTRACTL_END;
- HRESULT hr;
- BEGIN_ENTRYPOINT_NOTHROW;
- hr = CorRuntimeHostBase::Start();
-
- END_ENTRYPOINT_NOTHROW;
-
- if (hr == S_FALSE)
+ // No point going further if the runtime is not running...
+ if (!IsRuntimeActive()
+ || !m_fStarted
+ )
{
- // This is to keep v1 behavior.
- hr = S_OK;
- }
- return(hr);
+ return HOST_E_CLRNOTAVAILABLE;
+ }
+
+
+ // Ensure that code is not loaded in the Default AppDomain
+ return HOST_E_INVALIDOPERATION;
}
-#endif // !defined(FEATURE_CORECLR)
-
-// *** ICorRuntimeHost methods ***
-#ifndef FEATURE_CORECLR
-// Returns an object for configuring the runtime prior to
-// it starting. If the runtime has been initialized this
-// routine returns an error. See ICorConfiguration.
-HRESULT CorHost2::GetConfiguration(ICorConfiguration** pConfiguration)
+HRESULT ExecuteInAppDomainHelper(FExecuteInAppDomainCallback pCallback,
+ void * cookie)
{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- if (!pConfiguration)
- return E_POINTER;
- HRESULT hr=E_FAIL;
- BEGIN_ENTRYPOINT_NOTHROW;
- if (!m_Started)
- {
- *pConfiguration = (ICorConfiguration *) this;
- AddRef();
- hr=S_OK;
- }
- END_ENTRYPOINT_NOTHROW;
- // Cannot obtain configuration after the runtime is started
- return hr;
-}
-#endif // FEATURE_CORECLR
+ STATIC_CONTRACT_THROWS;
+ STATIC_CONTRACT_SO_INTOLERANT;
-extern BOOL g_fWeOwnProcess;
+ HRESULT hr = S_OK;
-CorHost2::CorHost2()
-{
- LIMITED_METHOD_CONTRACT;
+ BEGIN_SO_TOLERANT_CODE(GetThread());
+ hr = pCallback(cookie);
+ END_SO_TOLERANT_CODE;
-#ifdef FEATURE_CORECLR
- m_fStarted = FALSE;
- m_fFirstToLoadCLR = FALSE;
- m_fAppDomainCreated = FALSE;
-#endif // FEATURE_CORECLR
+ return hr;
}
-static DangerousNonHostedSpinLock lockOnlyOneToInvokeStart;
-
-STDMETHODIMP CorHost2::Start()
+HRESULT CorHost2::ExecuteInAppDomain(DWORD dwAppDomainId,
+ FExecuteInAppDomainCallback pCallback,
+ void * cookie)
{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- ENTRY_POINT;
- }CONTRACTL_END;
-
- HRESULT hr;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
-#ifdef FEATURE_CORECLR
- // Ensure that only one thread at a time gets in here
- DangerousNonHostedSpinLockHolder lockHolder(&lockOnlyOneToInvokeStart);
-
- // To provide the complete semantic of Start/Stop in context of a given host, we check m_fStarted and let
- // them invoke the Start only if they have not already. Likewise, they can invoke the Stop method
- // only if they have invoked Start prior to that.
- //
- // This prevents a host from invoking Stop twice and hitting the refCount to zero, when another
- // host is using the CLR, as CLR instance sharing across hosts is a scenario for CoreCLR.
- if (g_fEEStarted)
+ // No point going further if the runtime is not running...
+ if (!IsRuntimeActive()
+ || !m_fStarted
+ )
{
- hr = S_OK;
- // CoreCLR is already running - but was Start already invoked by this host?
- if (m_fStarted)
- {
- // This host had already invoked the Start method - return them an error
- hr = HOST_E_INVALIDOPERATION;
- }
- else
- {
- // Increment the global (and dynamic) refCount...
- FastInterlockIncrement(&m_RefCount);
+ return HOST_E_CLRNOTAVAILABLE;
+ }
- // And set our flag that this host has invoked the Start...
- m_fStarted = TRUE;
- }
- }
- else
-#endif // FEATURE_CORECLR
+ if(!(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN))
{
- // Using managed C++ libraries, its possible that when the runtime is already running,
- // MC++ will use CorBindToRuntimeEx to make callbacks into specific appdomain of its
- // choice. Now, CorBindToRuntimeEx results in CorHost2::CreateObject being invoked
- // that will set runtime hosted flag "g_fHostConfig |= CLRHOSTED".
- //
- // For the case when managed code started without CLR hosting and MC++ does a
- // CorBindToRuntimeEx, setting the CLR hosted flag is incorrect.
- //
- // Thus, before we attempt to start the runtime, we save the status of it being
- // already running or not. Next, if we are able to successfully start the runtime
- // and ONLY if it was not started earlier will we set the hosted flag below.
- if (!g_fEEStarted)
- {
- g_fHostConfig |= CLRHOSTED;
- }
-
- hr = CorRuntimeHostBase::Start();
- if (SUCCEEDED(hr))
- {
-#ifdef FEATURE_CORECLR
- // Set our flag that this host invoked the Start method.
- m_fStarted = TRUE;
-
- // And they also loaded the CoreCLR DLL in the memory (for this version).
- // This is a special flag as the host that has got this flag set will be allowed
- // to repeatedly invoke Stop method (without corresponding Start method invocations).
- // This is to support scenarios like that of Office where they need to bring down
- // the CLR at any cost.
- //
- // So, if you want to do that, just make sure you are the first host to load the
- // specific version of CLR in memory AND start it.
- m_fFirstToLoadCLR = TRUE;
-#endif // FEATURE_CORECLR
- if (FastInterlockIncrement(&m_RefCount) != 1)
- {
- }
- else
- {
- if (g_fWeOwnProcess)
- {
- // Runtime is started by a managed exe. Bump the ref-count, so that
- // matching Start/Stop does not stop runtime.
- FastInterlockIncrement(&m_RefCount);
- }
- }
- }
+ // Ensure that code is not loaded in the Default AppDomain
+ if (dwAppDomainId == DefaultADID)
+ return HOST_E_INVALIDOPERATION;
}
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
+ // Moved this here since no point validating the pointer
+ // if the basic checks [above] fail
+ if( pCallback == NULL)
+ return E_POINTER;
-// Starts the runtime. This is equivalent to CoInitializeEE();
-HRESULT CorRuntimeHostBase::Start()
-{
CONTRACTL
{
NOTHROW;
- DISABLED(GC_TRIGGERS);
- ENTRY_POINT;
+ if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+ ENTRY_POINT; // This is called by a host.
}
CONTRACTL_END;
HRESULT hr = S_OK;
BEGIN_ENTRYPOINT_NOTHROW;
+ BEGIN_EXTERNAL_ENTRYPOINT(&hr);
+ GCX_COOP_THREAD_EXISTS(GET_THREAD());
+ ENTER_DOMAIN_ID(ADID(dwAppDomainId))
{
- m_Started = TRUE;
-#ifdef FEATURE_EVENT_TRACE
- g_fEEHostedStartup = TRUE;
-#endif // FEATURE_EVENT_TRACE
- hr = InitializeEE(COINITEE_DEFAULT);
+ // We are calling an unmanaged function pointer, either an unmanaged function, or a marshaled out delegate.
+ // The thread should be in preemptive mode, and SO_Tolerant.
+ GCX_PREEMP();
+ hr=ExecuteInAppDomainHelper (pCallback, cookie);
}
+ END_DOMAIN_TRANSITION;
+ END_EXTERNAL_ENTRYPOINT;
END_ENTRYPOINT_NOTHROW;
return hr;
}
-#if !defined(FEATURE_CORECLR) // simple hosting
-HRESULT CorHost::Stop()
+#define EMPTY_STRING_TO_NULL(s) {if(s && s[0] == 0) {s=NULL;};}
+
+HRESULT CorHost2::_CreateAppDomain(
+ LPCWSTR wszFriendlyName,
+ DWORD dwFlags,
+ LPCWSTR wszAppDomainManagerAssemblyName,
+ LPCWSTR wszAppDomainManagerTypeName,
+ int nProperties,
+ LPCWSTR* pPropertyNames,
+ LPCWSTR* pPropertyValues,
+ DWORD* pAppDomainID)
{
CONTRACTL
{
NOTHROW;
- ENTRY_POINT;
if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+ ENTRY_POINT; // This is called by a host.
}
CONTRACTL_END;
- // This must remain this way (that is doing nothing) for backwards compat reasons.
- return S_OK;
-}
-#endif // !defined(FEATURE_CORECLR)
+ HRESULT hr=S_OK;
-HRESULT CorHost2::Stop()
-{
- CONTRACTL
- {
- NOTHROW;
- ENTRY_POINT; // We're bringing the EE down, so no point in probing
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- }
- CONTRACTL_END;
- if (!g_fEEStarted)
+ //cannot call the function more than once when single appDomain is allowed
+ if (m_fAppDomainCreated && (m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN))
{
- return E_UNEXPECTED;
+ return HOST_E_INVALIDOPERATION;
}
- HRESULT hr=S_OK;
+
+ //normalize empty strings
+ EMPTY_STRING_TO_NULL(wszFriendlyName);
+ EMPTY_STRING_TO_NULL(wszAppDomainManagerAssemblyName);
+ EMPTY_STRING_TO_NULL(wszAppDomainManagerTypeName);
+
+ if(pAppDomainID==NULL)
+ return E_POINTER;
+
+ if (!m_fStarted)
+ return HOST_E_INVALIDOPERATION;
+
+ if(wszFriendlyName == NULL)
+ return E_INVALIDARG;
+
+ if((wszAppDomainManagerAssemblyName == NULL) != (wszAppDomainManagerTypeName == NULL))
+ return E_INVALIDARG;
+
BEGIN_ENTRYPOINT_NOTHROW;
-#ifdef FEATURE_CORECLR
- // Is this host eligible to invoke the Stop method?
- if ((!m_fStarted) && (!m_fFirstToLoadCLR))
+ BEGIN_EXTERNAL_ENTRYPOINT(&hr);
+ GCX_COOP_THREAD_EXISTS(GET_THREAD());
+
+ AppDomainCreationHolder<AppDomain> pDomain;
+
+ // If StartupFlag specifies single appDomain then return the default domain instead of creating new one
+ if(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN)
{
- // Well - since this host never invoked Start, it is not eligible to invoke Stop.
- // Semantically, for such a host, CLR is not available in the process. The only
- // exception to this condition is the host that first loaded this version of the
- // CLR and invoked Start method. For details, refer to comments in CorHost2::Start implementation.
- hr = HOST_E_CLRNOTAVAILABLE;
+ pDomain.Assign(SystemDomain::System()->DefaultDomain());
}
else
-#endif // FEATURE_CORECLR
- {
- while (TRUE)
- {
- LONG refCount = m_RefCount;
- if (refCount == 0)
- {
- #ifdef FEATURE_CORECLR
- hr = HOST_E_CLRNOTAVAILABLE;
- #else // !FEATURE_CORECLR
- hr= E_UNEXPECTED;
- #endif // FEATURE_CORECLR
- break;
- }
- else
- if (FastInterlockCompareExchange(&m_RefCount, refCount - 1, refCount) == refCount)
- {
- #ifdef FEATURE_CORECLR
- // Indicate that we have got a Stop for a corresponding Start call from the
- // Host. Semantically, CoreCLR has stopped for them.
- m_fStarted = FALSE;
- #endif // FEATURE_CORECLR
-
- if (refCount > 1)
- {
- hr=S_FALSE;
- break;
- }
- else
- {
- break;
- }
- }
- }
- }
-#ifndef FEATURE_CORECLR
- if (hr==S_OK)
{
- EPolicyAction action = GetEEPolicy()->GetDefaultAction(OPR_ProcessExit, NULL);
- if (action > eExitProcess)
- {
- g_fFastExitProcess = 1;
- }
- EEShutDown(FALSE);
+ AppDomain::CreateUnmanagedObject(pDomain);
}
-#endif // FEATURE_CORECLR
- END_ENTRYPOINT_NOTHROW;
-#ifndef FEATURE_CORECLR
- if (hr == S_OK)
+ ETW::LoaderLog::DomainLoad(pDomain, (LPWSTR)wszFriendlyName);
+
+ if (dwFlags & APPDOMAIN_IGNORE_UNHANDLED_EXCEPTIONS)
{
- if (m_HostControl)
- {
- m_HostControl->Release();
- m_HostControl = NULL;
- }
+ pDomain->SetIgnoreUnhandledExceptions();
}
-#endif // FEATURE_CORECLR
-
- return hr;
-}
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
+ if (dwFlags & APPDOMAIN_SECURITY_FORBID_CROSSAD_REVERSE_PINVOKE)
+ pDomain->SetReversePInvokeCannotEnter();
-// Creates a domain in the runtime. The identity array is
-// a pointer to an array TYPE containing IIdentity objects defining
-// the security identity.
-HRESULT CorRuntimeHostBase::CreateDomain(LPCWSTR pwzFriendlyName,
- IUnknown* pIdentityArray, // Optional
- IUnknown ** pAppDomain)
-{
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_ENTRY_POINT;
+ if (dwFlags & APPDOMAIN_FORCE_TRIVIAL_WAIT_OPERATIONS)
+ pDomain->SetForceTrivialWaitOperations();
- return CreateDomainEx(pwzFriendlyName,
- NULL,
- NULL,
- pAppDomain);
-}
+
+#ifdef PROFILING_SUPPORTED
+ EX_TRY
+#endif
+ {
+ pDomain->SetAppDomainManagerInfo(wszAppDomainManagerAssemblyName,wszAppDomainManagerTypeName,eInitializeNewDomainFlags_None);
+ GCX_COOP();
+
+ struct
+ {
+ STRINGREF friendlyName;
+ PTRARRAYREF propertyNames;
+ PTRARRAYREF propertyValues;
+ STRINGREF sandboxName;
+ OBJECTREF setupInfo;
+ OBJECTREF adSetup;
+ } _gc;
-// Returns the default domain.
-HRESULT CorRuntimeHostBase::GetDefaultDomain(IUnknown ** pAppDomain)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- } CONTRACTL_END;
+ ZeroMemory(&_gc,sizeof(_gc));
- HRESULT hr = E_UNEXPECTED;
- if (!g_fEEStarted)
- return hr;
+ GCPROTECT_BEGIN(_gc)
+ _gc.friendlyName=StringObject::NewString(wszFriendlyName);
+
+ if(nProperties>0)
+ {
+ _gc.propertyNames = (PTRARRAYREF) AllocateObjectArray(nProperties, g_pStringClass);
+ _gc.propertyValues= (PTRARRAYREF) AllocateObjectArray(nProperties, g_pStringClass);
+ for (int i=0;i< nProperties;i++)
+ {
+ STRINGREF obj = StringObject::NewString(pPropertyNames[i]);
+ _gc.propertyNames->SetAt(i, obj);
+
+ obj = StringObject::NewString(pPropertyValues[i]);
+ _gc.propertyValues->SetAt(i, obj);
+ }
+ }
- if( pAppDomain == NULL)
- return E_POINTER;
+ if (dwFlags & APPDOMAIN_SECURITY_SANDBOXED)
+ {
+ _gc.sandboxName = StringObject::NewString(W("Internet"));
+ }
+ else
+ {
+ _gc.sandboxName = StringObject::NewString(W("FullTrust"));
+ }
- BEGIN_ENTRYPOINT_NOTHROW;
+ MethodDescCallSite prepareDataForSetup(METHOD__APP_DOMAIN__PREPARE_DATA_FOR_SETUP);
- BEGIN_EXTERNAL_ENTRYPOINT(&hr);
- {
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
+ ARG_SLOT args[8];
+ args[0]=ObjToArgSlot(_gc.friendlyName);
+ args[1]=ObjToArgSlot(NULL);
+ args[2]=ObjToArgSlot(NULL);
+ args[3]=ObjToArgSlot(NULL);
+ //CoreCLR shouldn't have dependencies on parent app domain.
+ args[4]=ObjToArgSlot(NULL);
+ args[5]=ObjToArgSlot(_gc.sandboxName);
+ args[6]=ObjToArgSlot(_gc.propertyNames);
+ args[7]=ObjToArgSlot(_gc.propertyValues);
- if (SystemDomain::System()) {
- AppDomain* pCom = SystemDomain::System()->DefaultDomain();
- if(pCom)
- hr = pCom->GetComIPForExposedObject(pAppDomain);
- }
+ _gc.setupInfo=prepareDataForSetup.Call_RetOBJECTREF(args);
- }
- END_EXTERNAL_ENTRYPOINT;
- END_ENTRYPOINT_NOTHROW;
+ //
+ // Get the new flag values and set it to the domain
+ //
+ PTRARRAYREF handleArrayObj = (PTRARRAYREF) ObjectToOBJECTREF(_gc.setupInfo);
+ _gc.adSetup = ObjectToOBJECTREF(handleArrayObj->GetAt(1));
- return hr;
-}
-// Returns the default domain.
-HRESULT CorRuntimeHostBase::CurrentDomain(IUnknown ** pAppDomain)
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- }
- CONTRACTL_END;
+ pDomain->DoSetup(&_gc.setupInfo);
- HRESULT hr = E_UNEXPECTED;
- if (!g_fEEStarted)
- return hr;
+ pDomain->CacheStringsForDAC();
+
+ GCPROTECT_END();
- if( pAppDomain == NULL) return E_POINTER;
+ *pAppDomainID=pDomain->GetId().m_dwId;
- BEGIN_ENTRYPOINT_NOTHROW;
+ // If StartupFlag specifies single appDomain then set the flag that appdomain has already been created
+ if(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN)
+ {
+ m_fAppDomainCreated = TRUE;
+ }
+ }
+#ifdef PROFILING_SUPPORTED
+ EX_HOOK
+ {
+ // Need the first assembly loaded in to get any data on an app domain.
+ {
+ BEGIN_PIN_PROFILER(CORProfilerTrackAppDomainLoads());
+ GCX_PREEMP();
+ g_profControlBlock.pProfInterface->AppDomainCreationFinished((AppDomainID)(AppDomain*) pDomain, GET_EXCEPTION()->GetHR());
+ END_PIN_PROFILER();
+ }
+ }
+ EX_END_HOOK;
- BEGIN_EXTERNAL_ENTRYPOINT(&hr);
+ // Need the first assembly loaded in to get any data on an app domain.
{
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
+ BEGIN_PIN_PROFILER(CORProfilerTrackAppDomainLoads());
+ GCX_PREEMP();
+ g_profControlBlock.pProfInterface->AppDomainCreationFinished((AppDomainID)(AppDomain*) pDomain, S_OK);
+ END_PIN_PROFILER();
+ }
+#endif // PROFILING_SUPPORTED
- AppDomain* pCom = ::GetAppDomain();
- if(pCom)
- hr = pCom->GetComIPForExposedObject(pAppDomain);
+ // DoneCreating releases ownership of AppDomain. After this call, there should be no access to pDomain.
+ pDomain.DoneCreating();
- }
END_EXTERNAL_ENTRYPOINT;
+
END_ENTRYPOINT_NOTHROW;
return hr;
-};
-#endif // FEATURE_COMINTEROP && !FEATURE_CORECLR
+};
-HRESULT CorHost2::GetCurrentAppDomainId(DWORD *pdwAppDomainId)
+HRESULT CorHost2::_CreateDelegate(
+ DWORD appDomainID,
+ LPCWSTR wszAssemblyName,
+ LPCWSTR wszClassName,
+ LPCWSTR wszMethodName,
+ INT_PTR* fnPtr)
{
+
CONTRACTL
{
NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
+ if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+ ENTRY_POINT; // This is called by a host.
}
CONTRACTL_END;
- // No point going further if the runtime is not running...
- // We use CanRunManagedCode() instead of IsRuntimeActive() because this allows us
- // to specify test using the form that does not trigger a GC.
- if (!(g_fEEStarted && CanRunManagedCode(LoaderLockCheck::None))
-#ifdef FEATURE_CORECLR
- || !m_fStarted
-#endif
- )
- {
- return HOST_E_CLRNOTAVAILABLE;
- }
+ HRESULT hr=S_OK;
+
+ EMPTY_STRING_TO_NULL(wszAssemblyName);
+ EMPTY_STRING_TO_NULL(wszClassName);
+ EMPTY_STRING_TO_NULL(wszMethodName);
+
+ if (fnPtr == NULL)
+ return E_POINTER;
+ *fnPtr = NULL;
+
+ if(wszAssemblyName == NULL)
+ return E_INVALIDARG;
- HRESULT hr = S_OK;
+ if(wszClassName == NULL)
+ return E_INVALIDARG;
- BEGIN_ENTRYPOINT_NOTHROW;
+ if(wszMethodName == NULL)
+ return E_INVALIDARG;
+
+ if (!m_fStarted)
+ return HOST_E_INVALIDOPERATION;
- if(pdwAppDomainId == NULL)
- {
- hr = E_POINTER;
- }
- else
+ if(!(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN))
{
- Thread *pThread = GetThread();
- if (!pThread)
- {
- hr = E_UNEXPECTED;
- }
- else
- {
- *pdwAppDomainId = SystemDomain::GetCurrentDomain()->GetId().m_dwId;
- }
+ // Ensure that code is not loaded in the Default AppDomain
+ if (appDomainID == DefaultADID)
+ return HOST_E_INVALIDOPERATION;
}
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
+ BEGIN_ENTRYPOINT_NOTHROW;
-HRESULT CorHost2::ExecuteApplication(LPCWSTR pwzAppFullName,
- DWORD dwManifestPaths,
- LPCWSTR *ppwzManifestPaths,
- DWORD dwActivationData,
- LPCWSTR *ppwzActivationData,
- int *pReturnValue)
-{
-#ifndef FEATURE_CORECLR
- // This API should not be called when the EE has already been started.
- HRESULT hr = E_UNEXPECTED;
- if (g_fEEStarted)
- return hr;
+ BEGIN_EXTERNAL_ENTRYPOINT(&hr);
+ GCX_COOP_THREAD_EXISTS(GET_THREAD());
- //
- // We will let unhandled exceptions in the activated application
- // propagate all the way up, so that ClickOnce semi-trusted apps
- // can participate in the Dr Watson program, etc...
- //
+ MAKE_UTF8PTR_FROMWIDE(szAssemblyName, wszAssemblyName);
+ MAKE_UTF8PTR_FROMWIDE(szClassName, wszClassName);
+ MAKE_UTF8PTR_FROMWIDE(szMethodName, wszMethodName);
- CONTRACTL {
- THROWS;
- ENTRY_POINT;
- }
- CONTRACTL_END;
+ ADID id;
+ id.m_dwId=appDomainID;
- if (!pwzAppFullName)
- IfFailGo(E_POINTER);
+ ENTER_DOMAIN_ID(id)
- // Set the information about the application to execute.
- CorCommandLine::m_pwszAppFullName = (LPWSTR) pwzAppFullName;
- CorCommandLine::m_dwManifestPaths = dwManifestPaths;
- CorCommandLine::m_ppwszManifestPaths = (LPWSTR*) ppwzManifestPaths;
- CorCommandLine::m_dwActivationData = dwActivationData;
- CorCommandLine::m_ppwszActivationData = (LPWSTR*) ppwzActivationData;
+ GCX_PREEMP();
- // Start up the EE.
- IfFailGo(Start());
+ AssemblySpec spec;
+ spec.Init(szAssemblyName);
+ Assembly* pAsm=spec.LoadAssembly(FILE_ACTIVE);
- Thread *pThread;
- pThread = GetThread();
- if (pThread == NULL)
- pThread = SetupThreadNoThrow(&hr);
- if (pThread == NULL)
- goto ErrExit;
+ // we have no signature to check so allowing calling partially trusted code
+ // can result in an exploit
+ if (!pAsm->GetSecurityDescriptor()->IsFullyTrusted())
+ ThrowHR(COR_E_SECURITY);
- _ASSERTE (!pThread->PreemptiveGCDisabled());
+ TypeHandle th=pAsm->GetLoader()->LoadTypeByNameThrowing(pAsm,NULL,szClassName);
+ MethodDesc* pMD=NULL;
+
+ if (!th.IsTypeDesc())
+ {
+ pMD = MemberLoader::FindMethodByName(th.GetMethodTable(), szMethodName, MemberLoader::FM_Unique);
+ if (pMD == NULL)
+ {
+ // try again without the FM_Unique flag (error path)
+ pMD = MemberLoader::FindMethodByName(th.GetMethodTable(), szMethodName, MemberLoader::FM_Default);
+ if (pMD != NULL)
+ {
+ // the method exists but is overloaded
+ ThrowHR(COR_E_AMBIGUOUSMATCH);
+ }
+ }
+ }
- hr = S_OK;
+ if (pMD==NULL || !pMD->IsStatic() || pMD->ContainsGenericVariables())
+ ThrowHR(COR_E_MISSINGMETHOD);
- BEGIN_ENTRYPOINT_THROWS_WITH_THREAD(pThread);
- ENTER_DOMAIN_PTR(SystemDomain::System()->DefaultDomain(),ADV_DEFAULTAD)
+ // the target method must be decorated with AllowReversePInvokeCallsAttribute
+ if (!COMDelegate::IsMethodAllowedToSinkReversePInvoke(pMD))
+ ThrowHR(COR_E_SECURITY);
- SystemDomain::ActivateApplication(pReturnValue);
+ UMEntryThunk *pUMEntryThunk = GetAppDomain()->GetUMEntryThunkCache()->GetUMEntryThunk(pMD);
+ *fnPtr = (INT_PTR)pUMEntryThunk->GetCode();
END_DOMAIN_TRANSITION;
- END_ENTRYPOINT_THROWS_WITH_THREAD;
-ErrExit:
+ END_EXTERNAL_ENTRYPOINT;
+
+ END_ENTRYPOINT_NOTHROW;
+
return hr;
-#else // FEATURE_CORECLR
- return E_NOTIMPL;
-#endif
}
-#ifdef FEATURE_CORECLR
-/*
- * This method processes the arguments sent to the host which are then used
- * to invoke the main method.
- * Note -
- * [0] - points to the assemblyName that has been sent by the host.
- * The rest are the arguments sent to the assembly.
- * Also note, this might not always return the exact same identity as the cmdLine
- * used to invoke the method.
- *
- * For example :-
- * ActualCmdLine - Foo arg1 arg2.
- * (Host1) - Full_path_to_Foo arg1 arg2
-*/
-void SetCommandLineArgs(LPCWSTR pwzAssemblyPath, int argc, LPCWSTR* argv)
+HRESULT CorHost2::CreateAppDomainWithManager(
+ LPCWSTR wszFriendlyName,
+ DWORD dwFlags,
+ LPCWSTR wszAppDomainManagerAssemblyName,
+ LPCWSTR wszAppDomainManagerTypeName,
+ int nProperties,
+ LPCWSTR* pPropertyNames,
+ LPCWSTR* pPropertyValues,
+ DWORD* pAppDomainID)
{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
+ WRAPPER_NO_CONTRACT;
- struct _gc
- {
- PTRARRAYREF cmdLineArgs;
- } gc;
+ return _CreateAppDomain(
+ wszFriendlyName,
+ dwFlags,
+ wszAppDomainManagerAssemblyName,
+ wszAppDomainManagerTypeName,
+ nProperties,
+ pPropertyNames,
+ pPropertyValues,
+ pAppDomainID);
+}
- ZeroMemory(&gc, sizeof(gc));
- GCPROTECT_BEGIN(gc);
+HRESULT CorHost2::CreateDelegate(
+ DWORD appDomainID,
+ LPCWSTR wszAssemblyName,
+ LPCWSTR wszClassName,
+ LPCWSTR wszMethodName,
+ INT_PTR* fnPtr)
+{
+ WRAPPER_NO_CONTRACT;
- gc.cmdLineArgs = (PTRARRAYREF)AllocateObjectArray(argc + 1 /* arg[0] should be the exe name*/, g_pStringClass);
- OBJECTREF orAssemblyPath = StringObject::NewString(pwzAssemblyPath);
- gc.cmdLineArgs->SetAt(0, orAssemblyPath);
+ return _CreateDelegate(appDomainID, wszAssemblyName, wszClassName, wszMethodName, fnPtr);
+}
- for (int i = 0; i < argc; ++i)
+HRESULT CorHost2::Authenticate(ULONGLONG authKey)
+{
+ CONTRACTL
{
- OBJECTREF argument = StringObject::NewString(argv[i]);
- gc.cmdLineArgs->SetAt(i + 1, argument);
+ NOTHROW;
+ if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+ ENTRY_POINT; // This is called by a host.
}
+ CONTRACTL_END;
- MethodDescCallSite setCmdLineArgs(METHOD__ENVIRONMENT__SET_COMMAND_LINE_ARGS);
+ // Host authentication was used by Silverlight. It is no longer relevant for CoreCLR.
+ return S_OK;
+}
- ARG_SLOT args[] =
+HRESULT CorHost2::RegisterMacEHPort()
+{
+ CONTRACTL
{
- ObjToArgSlot(gc.cmdLineArgs),
- };
- setCmdLineArgs.Call(args);
+ NOTHROW;
+ if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+ ENTRY_POINT; // This is called by a host.
+ }
+ CONTRACTL_END;
- GCPROTECT_END();
+ return S_OK;
}
-HRESULT CorHost2::ExecuteAssembly(DWORD dwAppDomainId,
- LPCWSTR pwzAssemblyPath,
- int argc,
- LPCWSTR* argv,
- DWORD *pReturnValue)
+HRESULT CorHost2::SetStartupFlags(STARTUP_FLAGS flag)
{
CONTRACTL
{
- THROWS; // Throws...as we do not want it to swallow the managed exception
- ENTRY_POINT;
+ NOTHROW;
+ if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+ ENTRY_POINT; // This is called by a host.
}
CONTRACTL_END;
- // This is currently supported in default domain only
- if (dwAppDomainId != DefaultADID)
+ if (g_fEEStarted)
+ {
return HOST_E_INVALIDOPERATION;
+ }
- // No point going further if the runtime is not running...
- if (!IsRuntimeActive() || !m_fStarted)
- {
- return HOST_E_CLRNOTAVAILABLE;
- }
-
- if(!pwzAssemblyPath)
- return E_POINTER;
+ m_dwStartupFlags = flag;
- if(argc < 0)
- {
- return E_INVALIDARG;
- }
+ return S_OK;
+}
- if(argc > 0 && argv == NULL)
+
+
+HRESULT SuspendEEForPause()
+{
+ CONTRACTL
{
- return E_INVALIDARG;
+ NOTHROW;
+ MODE_PREEMPTIVE;
+ GC_TRIGGERS;
}
+ CONTRACTL_END;
HRESULT hr = S_OK;
- AppDomain *pCurDomain = SystemDomain::GetCurrentDomain();
+ // In CoreCLR, we always resume from the same thread that paused. So we can simply suspend the EE from this thread,
+ // knowing we'll restart from the same thread.
+ ThreadSuspend::SuspendEE(ThreadSuspend::SUSPEND_OTHER);
- Thread *pThread = GetThread();
- if (pThread == NULL)
+ return hr;
+}
+
+HRESULT RestartEEFromPauseAndSetResumeEvent()
+{
+ CONTRACTL
{
- pThread = SetupThreadNoThrow(&hr);
- if (pThread == NULL)
- {
- goto ErrExit;
- }
+ NOTHROW;
+ MODE_PREEMPTIVE;
+ GC_TRIGGERS;
}
+ CONTRACTL_END;
- if(pCurDomain->GetId().m_dwId != DefaultADID)
+ // see comments in SuspendEEFromPause
+ ThreadSuspend::RestartEE(FALSE, TRUE);
+
+ _ASSERTE(g_ClrResumeEvent.IsValid());
+ g_ClrResumeEvent.Set();
+
+ return S_OK;
+}
+
+
+
+CorExecutionManager::CorExecutionManager()
+ : m_dwFlags(0), m_pauseStartTime(0)
+{
+ LIMITED_METHOD_CONTRACT;
+ g_IsPaused = FALSE;
+ g_PauseTime = 0;
+}
+
+HRESULT CorExecutionManager::Pause(DWORD dwAppDomainId, DWORD dwFlags)
+{
+ CONTRACTL
{
- return HOST_E_INVALIDOPERATION;
+ NOTHROW;
+ if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+ ENTRY_POINT; // This is called by a host.
}
+ CONTRACTL_END;
- INSTALL_UNHANDLED_MANAGED_EXCEPTION_TRAP;
- INSTALL_UNWIND_AND_CONTINUE_HANDLER;
-
- _ASSERTE (!pThread->PreemptiveGCDisabled());
+ HRESULT hr = S_OK;
- Assembly *pAssembly = AssemblySpec::LoadAssembly(pwzAssemblyPath);
-#if defined(FEATURE_MULTICOREJIT)
- pCurDomain->GetMulticoreJitManager().AutoStartProfile(pCurDomain);
-#endif // defined(FEATURE_MULTICOREJIT)
+ if(g_IsPaused)
+ return E_FAIL;
+ EX_TRY
{
- GCX_COOP();
+ if(!g_ClrResumeEvent.IsValid())
+ g_ClrResumeEvent.CreateManualEvent(FALSE);
+ else
+ g_ClrResumeEvent.Reset();
- // Here we call the managed method that gets the cmdLineArgs array.
- SetCommandLineArgs(pwzAssemblyPath, argc, argv);
+ }
+ EX_CATCH_HRESULT(hr);
+
+ if (FAILED(hr))
+ return hr;
+
+ BEGIN_ENTRYPOINT_NOTHROW;
- PTRARRAYREF arguments = NULL;
- GCPROTECT_BEGIN(arguments);
+ m_dwFlags = dwFlags;
- arguments = (PTRARRAYREF)AllocateObjectArray(argc, g_pStringClass);
- for (int i = 0; i < argc; ++i)
- {
- STRINGREF argument = StringObject::NewString(argv[i]);
- arguments->SetAt(i, argument);
- }
- DWORD retval = pAssembly->ExecuteMainMethod(&arguments, TRUE /* waitForOtherThreads */);
- if (pReturnValue)
- {
- *pReturnValue = retval;
- }
+ if (SUCCEEDED(hr))
+ {
+ g_IsPaused = TRUE;
- GCPROTECT_END();
+ hr = SuspendEEForPause();
+ // Even though this is named with TickCount, it returns milliseconds
+ m_pauseStartTime = (INT64)CLRGetTickCount64();
}
- UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
- UNINSTALL_UNHANDLED_MANAGED_EXCEPTION_TRAP;
-
-ErrExit:
+ END_ENTRYPOINT_NOTHROW;
return hr;
}
-#endif
-HRESULT CorHost2::ExecuteInDefaultAppDomain(LPCWSTR pwzAssemblyPath,
- LPCWSTR pwzTypeName,
- LPCWSTR pwzMethodName,
- LPCWSTR pwzArgument,
- DWORD *pReturnValue)
+
+HRESULT CorExecutionManager::Resume(DWORD dwAppDomainId)
{
CONTRACTL
{
NOTHROW;
- ENTRY_POINT;
+ if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
+ ENTRY_POINT; // This is called by a host.
}
CONTRACTL_END;
- // No point going further if the runtime is not running...
- if (!IsRuntimeActive()
-#ifdef FEATURE_CORECLR
- || !m_fStarted
-#endif
- )
- {
- return HOST_E_CLRNOTAVAILABLE;
- }
-
-
-#ifndef FEATURE_CORECLR
- if(! (pwzAssemblyPath && pwzTypeName && pwzMethodName) )
- return E_POINTER;
-
HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
+ if(!g_IsPaused)
+ return E_FAIL;
+
+ // GCThread is the thread that did the Pause. Resume should also happen on that same thread
Thread *pThread = GetThread();
- if (pThread == NULL)
+ if(pThread != ThreadSuspend::GetSuspensionThread())
{
- pThread = SetupThreadNoThrow(&hr);
- if (pThread == NULL)
- {
- goto ErrExit;
- }
+ _ASSERTE(!"HOST BUG: The same thread that did Pause should do the Resume");
+ return E_FAIL;
}
- _ASSERTE (!pThread->PreemptiveGCDisabled());
+ BEGIN_ENTRYPOINT_NOTHROW;
- EX_TRY
- {
- ENTER_DOMAIN_PTR(SystemDomain::System()->DefaultDomain(),ADV_DEFAULTAD)
+ // Even though this is named with TickCount, it returns milliseconds
+ INT64 currTime = (INT64)CLRGetTickCount64();
+ _ASSERTE(currTime >= m_pauseStartTime);
+ _ASSERTE(m_pauseStartTime != 0);
- INSTALL_UNWIND_AND_CONTINUE_HANDLER;
+ g_PauseTime += (currTime - m_pauseStartTime);
+ g_IsPaused = FALSE;
- Assembly *pAssembly = AssemblySpec::LoadAssembly(pwzAssemblyPath);
+ hr = RestartEEFromPauseAndSetResumeEvent();
- SString szTypeName(pwzTypeName);
- StackScratchBuffer buff1;
- const char* szTypeNameUTF8 = szTypeName.GetUTF8(buff1);
- MethodTable *pMT = ClassLoader::LoadTypeByNameThrowing(pAssembly,
- NULL,
- szTypeNameUTF8).AsMethodTable();
- SString szMethodName(pwzMethodName);
- StackScratchBuffer buff;
- const char* szMethodNameUTF8 = szMethodName.GetUTF8(buff);
- MethodDesc *pMethodMD = MemberLoader::FindMethod(pMT, szMethodNameUTF8, &gsig_SM_Str_RetInt);
+ END_ENTRYPOINT_NOTHROW;
- if (!pMethodMD)
- {
- hr = COR_E_MISSINGMETHOD;
- }
- else
- {
- GCX_COOP();
+ return hr;
+}
+
+
+#endif //!DACCESS_COMPILE
- MethodDescCallSite method(pMethodMD);
+#ifndef DACCESS_COMPILE
+SVAL_IMPL(STARTUP_FLAGS, CorHost2, m_dwStartupFlags = STARTUP_CONCURRENT_GC);
+#else
+SVAL_IMPL(STARTUP_FLAGS, CorHost2, m_dwStartupFlags);
+#endif
- STRINGREF sref = NULL;
- GCPROTECT_BEGIN(sref);
+STARTUP_FLAGS CorHost2::GetStartupFlags()
+{
+ return m_dwStartupFlags;
+}
- if (pwzArgument)
- sref = StringObject::NewString(pwzArgument);
+#ifndef DACCESS_COMPILE
- ARG_SLOT MethodArgs[] =
- {
- ObjToArgSlot(sref)
- };
- DWORD retval = method.Call_RetI4(MethodArgs);
- if (pReturnValue)
- {
- *pReturnValue = retval;
- }
- GCPROTECT_END();
+#ifdef FEATURE_COMINTEROP
+
+// Enumerate currently existing domains.
+HRESULT CorRuntimeHostBase::EnumDomains(HDOMAINENUM *hEnum)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ MODE_PREEMPTIVE;
+ WRAPPER(GC_TRIGGERS);
+ ENTRY_POINT;
}
+ CONTRACTL_END;
- UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
- END_DOMAIN_TRANSITION;
+ if(hEnum == NULL) return E_POINTER;
+
+ // Thread setup happens in BEGIN_EXTERNAL_ENTRYPOINT below.
+ // If the runtime has not started, we have nothing to do.
+ if (!g_fEEStarted)
+ {
+ return HOST_E_CLRNOTAVAILABLE;
}
- EX_CATCH_HRESULT(hr);
-ErrExit:
+ HRESULT hr = E_OUTOFMEMORY;
+ *hEnum = NULL;
+ BEGIN_ENTRYPOINT_NOTHROW;
+
+ BEGIN_EXTERNAL_ENTRYPOINT(&hr)
+ AppDomainIterator *pEnum = new (nothrow) AppDomainIterator(FALSE);
+ if(pEnum) {
+ *hEnum = (HDOMAINENUM) pEnum;
+ hr = S_OK;
+ }
+ END_EXTERNAL_ENTRYPOINT;
END_ENTRYPOINT_NOTHROW;
return hr;
-#else // FEATURE_CORECLR
- // Ensure that code is not loaded in the Default AppDomain
- return HOST_E_INVALIDOPERATION;
-#endif
}
-HRESULT ExecuteInAppDomainHelper(FExecuteInAppDomainCallback pCallback,
- void * cookie)
-{
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_SO_INTOLERANT;
-
- HRESULT hr = S_OK;
+#endif // FEATURE_COMINTEROP
- BEGIN_SO_TOLERANT_CODE(GetThread());
- hr = pCallback(cookie);
- END_SO_TOLERANT_CODE;
+extern "C"
+HRESULT GetCLRRuntimeHost(REFIID riid, IUnknown **ppUnk)
+{
+ WRAPPER_NO_CONTRACT;
- return hr;
+ return CorHost2::CreateObject(riid, (void**)ppUnk);
}
-HRESULT CorHost2::ExecuteInAppDomain(DWORD dwAppDomainId,
- FExecuteInAppDomainCallback pCallback,
- void * cookie)
+
+STDMETHODIMP CorHost2::UnloadAppDomain(DWORD dwDomainId, BOOL fWaitUntilDone)
{
+ WRAPPER_NO_CONTRACT;
+ STATIC_CONTRACT_SO_TOLERANT;
- // No point going further if the runtime is not running...
- if (!IsRuntimeActive()
-#ifdef FEATURE_CORECLR
- || !m_fStarted
-#endif // FEATURE_CORECLR
- )
- {
- return HOST_E_CLRNOTAVAILABLE;
- }
+ if (!m_fStarted)
+ return HOST_E_INVALIDOPERATION;
-#ifdef FEATURE_CORECLR
- if(!(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN))
+ if(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN)
{
- // Ensure that code is not loaded in the Default AppDomain
- if (dwAppDomainId == DefaultADID)
- return HOST_E_INVALIDOPERATION;
+ if (!g_fEEStarted)
+ {
+ return HOST_E_CLRNOTAVAILABLE;
+ }
+
+ if(!m_fAppDomainCreated)
+ {
+ return HOST_E_INVALIDOPERATION;
+ }
+
+ HRESULT hr=S_OK;
+ BEGIN_ENTRYPOINT_NOTHROW;
+
+ if (!m_fFirstToLoadCLR)
+ {
+ _ASSERTE(!"Not reachable");
+ hr = HOST_E_CLRNOTAVAILABLE;
+ }
+ else
+ {
+ LONG refCount = m_RefCount;
+ if (refCount == 0)
+ {
+ hr = HOST_E_CLRNOTAVAILABLE;
+ }
+ else
+ if (1 == refCount)
+ {
+ // Stop coreclr on unload.
+ m_fStarted = FALSE;
+ EEShutDown(FALSE);
+ }
+ else
+ {
+ _ASSERTE(!"Not reachable");
+ hr = S_FALSE;
+ }
+ }
+ END_ENTRYPOINT_NOTHROW;
+
+ return hr;
}
-#endif // FEATURE_CORECLR
+ else
- // Moved this here since no point validating the pointer
- // if the basic checks [above] fail
- if( pCallback == NULL)
- return E_POINTER;
+ return CorRuntimeHostBase::UnloadAppDomain(dwDomainId, fWaitUntilDone);
+}
+HRESULT CorRuntimeHostBase::UnloadAppDomain(DWORD dwDomainId, BOOL fSync)
+{
CONTRACTL
{
NOTHROW;
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- ENTRY_POINT; // This is called by a host.
+ GC_TRIGGERS;
+ MODE_ANY;
+ FORBID_FAULT; // Unloading domains cannot fail due to OOM
+ ENTRY_POINT;
}
CONTRACTL_END;
HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
- BEGIN_EXTERNAL_ENTRYPOINT(&hr);
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
- ENTER_DOMAIN_ID(ADID(dwAppDomainId))
+ // No point going further if the runtime is not running...
{
- // We are calling an unmanaged function pointer, either an unmanaged function, or a marshaled out delegate.
- // The thread should be in preemptive mode, and SO_Tolerant.
- GCX_PREEMP();
- hr=ExecuteInAppDomainHelper (pCallback, cookie);
+ // In IsRuntimeActive, we will call CanRunManagedCode that will
+ // check if the current thread has taken the loader lock or not,
+ // if MDA is supported. To do the check, MdaLoaderLock::ReportViolation
+ // will be invoked that will internally end up invoking
+ // MdaFactory<MdaXmlElement>::GetNext that will use the "new" operator
+ // that has the "FAULT" contract set, resulting in FAULT_VIOLATION since
+ // this method has the FORBID_FAULT contract set above.
+ //
+ // However, for a thread that holds the loader lock, unloading the appDomain is
+ // not a supported scenario. Thus, we should not be ending up in this code
+ // path for the FAULT violation.
+ //
+ // Hence, the CONTRACT_VIOLATION below for overriding the FORBID_FAULT
+ // for this scope only.
+ CONTRACT_VIOLATION(FaultViolation);
+ if (!IsRuntimeActive()
+ || !m_fStarted
+ )
+ {
+ return HOST_E_CLRNOTAVAILABLE;
+ }
}
- END_DOMAIN_TRANSITION;
- END_EXTERNAL_ENTRYPOINT;
+
+ BEGIN_ENTRYPOINT_NOTHROW;
+
+ // We do not use BEGIN_EXTERNAL_ENTRYPOINT here because
+ // we do not want to setup Thread. Process may be OOM, and we want Unload
+ // to work.
+ hr = AppDomain::UnloadById(ADID(dwDomainId), fSync);
+
END_ENTRYPOINT_NOTHROW;
return hr;
}
-#define EMPTY_STRING_TO_NULL(s) {if(s && s[0] == 0) {s=NULL;};}
+//*****************************************************************************
+// Fiber Methods
+//*****************************************************************************
-HRESULT CorHost2::_CreateAppDomain(
- LPCWSTR wszFriendlyName,
- DWORD dwFlags,
- LPCWSTR wszAppDomainManagerAssemblyName,
- LPCWSTR wszAppDomainManagerTypeName,
- int nProperties,
- LPCWSTR* pPropertyNames,
- LPCWSTR* pPropertyValues,
-#if !defined(FEATURE_CORECLR)
- ICLRPrivBinder* pBinder,
-#endif
- DWORD* pAppDomainID)
+HRESULT CorRuntimeHostBase::LocksHeldByLogicalThread(DWORD *pCount)
{
+ if (!pCount)
+ return E_POINTER;
+
CONTRACTL
{
NOTHROW;
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- ENTRY_POINT; // This is called by a host.
- }
- CONTRACTL_END;
-
- HRESULT hr=S_OK;
-
-#ifdef FEATURE_CORECLR
- //cannot call the function more than once when single appDomain is allowed
- if (m_fAppDomainCreated && (m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN))
- {
- return HOST_E_INVALIDOPERATION;
- }
-#endif
-
- //normalize empty strings
- EMPTY_STRING_TO_NULL(wszFriendlyName);
- EMPTY_STRING_TO_NULL(wszAppDomainManagerAssemblyName);
- EMPTY_STRING_TO_NULL(wszAppDomainManagerTypeName);
-
- if(pAppDomainID==NULL)
- return E_POINTER;
-
-#ifdef FEATURE_CORECLR
- if (!m_fStarted)
- return HOST_E_INVALIDOPERATION;
-#endif // FEATURE_CORECLR
-
- if(wszFriendlyName == NULL)
- return E_INVALIDARG;
-
- if((wszAppDomainManagerAssemblyName == NULL) != (wszAppDomainManagerTypeName == NULL))
- return E_INVALIDARG;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr);
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
-
- AppDomainCreationHolder<AppDomain> pDomain;
-
-#ifdef FEATURE_CORECLR
- // If StartupFlag specifies single appDomain then return the default domain instead of creating new one
- if(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN)
- {
- pDomain.Assign(SystemDomain::System()->DefaultDomain());
- }
- else
-#endif
- {
- AppDomain::CreateUnmanagedObject(pDomain);
- }
-
- ETW::LoaderLog::DomainLoad(pDomain, (LPWSTR)wszFriendlyName);
-
-#ifdef FEATURE_CORECLR
- if (dwFlags & APPDOMAIN_IGNORE_UNHANDLED_EXCEPTIONS)
- {
- pDomain->SetIgnoreUnhandledExceptions();
- }
-#endif // FEATURE_CORECLR
-
- if (dwFlags & APPDOMAIN_SECURITY_FORBID_CROSSAD_REVERSE_PINVOKE)
- pDomain->SetReversePInvokeCannotEnter();
-
- if (dwFlags & APPDOMAIN_FORCE_TRIVIAL_WAIT_OPERATIONS)
- pDomain->SetForceTrivialWaitOperations();
-
-#if !defined(FEATURE_CORECLR)
- if (pBinder != NULL)
- pDomain->SetLoadContextHostBinder(pBinder);
-#endif
-
-#ifdef PROFILING_SUPPORTED
- EX_TRY
-#endif
- {
- pDomain->SetAppDomainManagerInfo(wszAppDomainManagerAssemblyName,wszAppDomainManagerTypeName,eInitializeNewDomainFlags_None);
-
- GCX_COOP();
-
- struct
- {
- STRINGREF friendlyName;
- PTRARRAYREF propertyNames;
- PTRARRAYREF propertyValues;
- STRINGREF sandboxName;
- OBJECTREF setupInfo;
- OBJECTREF adSetup;
- } _gc;
-
- ZeroMemory(&_gc,sizeof(_gc));
-
- GCPROTECT_BEGIN(_gc)
- _gc.friendlyName=StringObject::NewString(wszFriendlyName);
-
- if(nProperties>0)
- {
- _gc.propertyNames = (PTRARRAYREF) AllocateObjectArray(nProperties, g_pStringClass);
- _gc.propertyValues= (PTRARRAYREF) AllocateObjectArray(nProperties, g_pStringClass);
- for (int i=0;i< nProperties;i++)
- {
- STRINGREF obj = StringObject::NewString(pPropertyNames[i]);
- _gc.propertyNames->SetAt(i, obj);
-
- obj = StringObject::NewString(pPropertyValues[i]);
- _gc.propertyValues->SetAt(i, obj);
- }
- }
-
- if (dwFlags & APPDOMAIN_SECURITY_SANDBOXED)
- {
- _gc.sandboxName = StringObject::NewString(W("Internet"));
- }
- else
- {
- _gc.sandboxName = StringObject::NewString(W("FullTrust"));
- }
-
- MethodDescCallSite prepareDataForSetup(METHOD__APP_DOMAIN__PREPARE_DATA_FOR_SETUP);
-
- ARG_SLOT args[8];
- args[0]=ObjToArgSlot(_gc.friendlyName);
- args[1]=ObjToArgSlot(NULL);
- args[2]=ObjToArgSlot(NULL);
- args[3]=ObjToArgSlot(NULL);
-#ifdef FEATURE_CORECLR
- //CoreCLR shouldn't have dependencies on parent app domain.
- args[4]=ObjToArgSlot(NULL);
-#else
- args[4]=PtrToArgSlot(GetAppDomain()->GetSecurityDescriptor());
-#endif //FEATURE_CORECLR
- args[5]=ObjToArgSlot(_gc.sandboxName);
- args[6]=ObjToArgSlot(_gc.propertyNames);
- args[7]=ObjToArgSlot(_gc.propertyValues);
-
- _gc.setupInfo=prepareDataForSetup.Call_RetOBJECTREF(args);
-
- //
- // Get the new flag values and set it to the domain
- //
- PTRARRAYREF handleArrayObj = (PTRARRAYREF) ObjectToOBJECTREF(_gc.setupInfo);
- _gc.adSetup = ObjectToOBJECTREF(handleArrayObj->GetAt(1));
-
-#ifndef FEATURE_CORECLR
- // We need to setup domain sorting before any other managed code runs in the domain, since that code
- // could end up caching data based on the sorting mode of the domain.
- pDomain->InitializeSorting(&_gc.adSetup);
- pDomain->InitializeHashing(&_gc.adSetup);
-#endif
-
- pDomain->DoSetup(&_gc.setupInfo);
-
- pDomain->CacheStringsForDAC();
-
- GCPROTECT_END();
-
- *pAppDomainID=pDomain->GetId().m_dwId;
-
-#ifdef FEATURE_CORECLR
- // If StartupFlag specifies single appDomain then set the flag that appdomain has already been created
- if(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN)
- {
- m_fAppDomainCreated = TRUE;
- }
-#endif
- }
-#ifdef PROFILING_SUPPORTED
- EX_HOOK
- {
- // Need the first assembly loaded in to get any data on an app domain.
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackAppDomainLoads());
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->AppDomainCreationFinished((AppDomainID)(AppDomain*) pDomain, GET_EXCEPTION()->GetHR());
- END_PIN_PROFILER();
- }
- }
- EX_END_HOOK;
-
- // Need the first assembly loaded in to get any data on an app domain.
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackAppDomainLoads());
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->AppDomainCreationFinished((AppDomainID)(AppDomain*) pDomain, S_OK);
- END_PIN_PROFILER();
- }
-#endif // PROFILING_SUPPORTED
-
- // DoneCreating releases ownership of AppDomain. After this call, there should be no access to pDomain.
- pDomain.DoneCreating();
-
- END_EXTERNAL_ENTRYPOINT;
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-
-};
-
-HRESULT CorHost2::_CreateDelegate(
- DWORD appDomainID,
- LPCWSTR wszAssemblyName,
- LPCWSTR wszClassName,
- LPCWSTR wszMethodName,
- INT_PTR* fnPtr)
-{
-
- CONTRACTL
- {
- NOTHROW;
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- ENTRY_POINT; // This is called by a host.
- }
- CONTRACTL_END;
-
- HRESULT hr=S_OK;
-
- EMPTY_STRING_TO_NULL(wszAssemblyName);
- EMPTY_STRING_TO_NULL(wszClassName);
- EMPTY_STRING_TO_NULL(wszMethodName);
-
- if (fnPtr == NULL)
- return E_POINTER;
- *fnPtr = NULL;
-
- if(wszAssemblyName == NULL)
- return E_INVALIDARG;
-
- if(wszClassName == NULL)
- return E_INVALIDARG;
-
- if(wszMethodName == NULL)
- return E_INVALIDARG;
-
-#ifdef FEATURE_CORECLR
- if (!m_fStarted)
- return HOST_E_INVALIDOPERATION;
-
- if(!(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN))
- {
- // Ensure that code is not loaded in the Default AppDomain
- if (appDomainID == DefaultADID)
- return HOST_E_INVALIDOPERATION;
- }
-#endif
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr);
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
-
- MAKE_UTF8PTR_FROMWIDE(szAssemblyName, wszAssemblyName);
- MAKE_UTF8PTR_FROMWIDE(szClassName, wszClassName);
- MAKE_UTF8PTR_FROMWIDE(szMethodName, wszMethodName);
-
- ADID id;
- id.m_dwId=appDomainID;
-
- ENTER_DOMAIN_ID(id)
-
- GCX_PREEMP();
-
- AssemblySpec spec;
- spec.Init(szAssemblyName);
- Assembly* pAsm=spec.LoadAssembly(FILE_ACTIVE);
-
- // we have no signature to check so allowing calling partially trusted code
- // can result in an exploit
- if (!pAsm->GetSecurityDescriptor()->IsFullyTrusted())
- ThrowHR(COR_E_SECURITY);
-
- TypeHandle th=pAsm->GetLoader()->LoadTypeByNameThrowing(pAsm,NULL,szClassName);
- MethodDesc* pMD=NULL;
-
- if (!th.IsTypeDesc())
- {
- pMD = MemberLoader::FindMethodByName(th.GetMethodTable(), szMethodName, MemberLoader::FM_Unique);
- if (pMD == NULL)
- {
- // try again without the FM_Unique flag (error path)
- pMD = MemberLoader::FindMethodByName(th.GetMethodTable(), szMethodName, MemberLoader::FM_Default);
- if (pMD != NULL)
- {
- // the method exists but is overloaded
- ThrowHR(COR_E_AMBIGUOUSMATCH);
- }
- }
- }
-
- if (pMD==NULL || !pMD->IsStatic() || pMD->ContainsGenericVariables())
- ThrowHR(COR_E_MISSINGMETHOD);
-
-#ifdef FEATURE_CORECLR
- // the target method must be decorated with AllowReversePInvokeCallsAttribute
- if (!COMDelegate::IsMethodAllowedToSinkReversePInvoke(pMD))
- ThrowHR(COR_E_SECURITY);
-#endif
-
- UMEntryThunk *pUMEntryThunk = GetAppDomain()->GetUMEntryThunkCache()->GetUMEntryThunk(pMD);
- *fnPtr = (INT_PTR)pUMEntryThunk->GetCode();
-
- END_DOMAIN_TRANSITION;
-
- END_EXTERNAL_ENTRYPOINT;
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-#ifdef FEATURE_CORECLR
-HRESULT CorHost2::CreateAppDomainWithManager(
- LPCWSTR wszFriendlyName,
- DWORD dwFlags,
- LPCWSTR wszAppDomainManagerAssemblyName,
- LPCWSTR wszAppDomainManagerTypeName,
- int nProperties,
- LPCWSTR* pPropertyNames,
- LPCWSTR* pPropertyValues,
- DWORD* pAppDomainID)
-{
- WRAPPER_NO_CONTRACT;
-
- return _CreateAppDomain(
- wszFriendlyName,
- dwFlags,
- wszAppDomainManagerAssemblyName,
- wszAppDomainManagerTypeName,
- nProperties,
- pPropertyNames,
- pPropertyValues,
- pAppDomainID);
-}
-
-HRESULT CorHost2::CreateDelegate(
- DWORD appDomainID,
- LPCWSTR wszAssemblyName,
- LPCWSTR wszClassName,
- LPCWSTR wszMethodName,
- INT_PTR* fnPtr)
-{
- WRAPPER_NO_CONTRACT;
-
- return _CreateDelegate(appDomainID, wszAssemblyName, wszClassName, wszMethodName, fnPtr);
-}
-
-HRESULT CorHost2::Authenticate(ULONGLONG authKey)
-{
- CONTRACTL
- {
- NOTHROW;
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- ENTRY_POINT; // This is called by a host.
- }
- CONTRACTL_END;
-
- // Host authentication was used by Silverlight. It is no longer relevant for CoreCLR.
- return S_OK;
-}
-
-HRESULT CorHost2::RegisterMacEHPort()
-{
- CONTRACTL
- {
- NOTHROW;
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- ENTRY_POINT; // This is called by a host.
- }
- CONTRACTL_END;
-
- return S_OK;
-}
-
-HRESULT CorHost2::SetStartupFlags(STARTUP_FLAGS flag)
-{
- CONTRACTL
- {
- NOTHROW;
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- ENTRY_POINT; // This is called by a host.
- }
- CONTRACTL_END;
-
- if (g_fEEStarted)
- {
- return HOST_E_INVALIDOPERATION;
- }
-
- m_dwStartupFlags = flag;
-
- return S_OK;
-}
-
-#endif //FEATURE_CORECLR
-
-#ifndef FEATURE_CORECLR
-void PauseOneAppDomain(AppDomainIterator* pi)
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- EX_TRY {
- ENTER_DOMAIN_PTR(pi->GetDomain(),ADV_ITERATOR);
-
- MethodDescCallSite(METHOD__APP_DOMAIN__PAUSE).Call(NULL);
-
- END_DOMAIN_TRANSITION;
- } EX_CATCH {
- } EX_END_CATCH(SwallowAllExceptions);
-}
-
-void ResumeOneAppDomain(AppDomainIterator* pi)
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- EX_TRY {
- ENTER_DOMAIN_PTR(pi->GetDomain(),ADV_ITERATOR);
-
- MethodDescCallSite(METHOD__APP_DOMAIN__RESUME).Call(NULL);
-
- END_DOMAIN_TRANSITION;
- } EX_CATCH {
- } EX_END_CATCH(SwallowAllExceptions);
-}
-
-// see comments in SuspendEEFromPause
-DWORD WINAPI SuspendAndResumeForPause(LPVOID arg)
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_ANY;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- ThreadSuspend::SuspendEE(ThreadSuspend::SUSPEND_OTHER);
-
- g_PauseCompletedEvent.Set();
- g_ClrResumeEvent.Wait(INFINITE, FALSE);
-
- ThreadSuspend::RestartEE(FALSE, TRUE);
- return 0;
-}
-
-#endif // !FEATURE_CORECLR
-
-HRESULT SuspendEEForPause()
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_PREEMPTIVE;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
-#ifdef FEATURE_CORECLR
- // In CoreCLR, we always resume from the same thread that paused. So we can simply suspend the EE from this thread,
- // knowing we'll restart from the same thread.
- ThreadSuspend::SuspendEE(ThreadSuspend::SUSPEND_OTHER);
-#else
- // In the CLR, we can resume from a different thread than the one that paused. We can't call SuspendEE directly,
- // because we can't call RestartEE from another thread. So we queue a workitem to the ThreadPool to call SuspendEE
- // and ResumeEE on our behalf.
-
- EX_TRY
- {
- if (!ThreadpoolMgr::QueueUserWorkItem(SuspendAndResumeForPause, NULL, QUEUE_ONLY))
- {
- hr = HRESULT_FROM_GetLastError();
- }
- else
- {
- // wait for SuspendEE to complete before returning.
- g_PauseCompletedEvent.Wait(INFINITE,FALSE);
- }
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-#endif
-
- return hr;
-}
-
-HRESULT RestartEEFromPauseAndSetResumeEvent()
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_PREEMPTIVE;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- // see comments in SuspendEEFromPause
-#ifdef FEATURE_CORECLR
- ThreadSuspend::RestartEE(FALSE, TRUE);
-#else
- // setting the resume event below will restart the EE as well. We don't wait for the restart
- // to complete, because we'll sync with it next time we go to cooperative mode.
-#endif
-
- _ASSERTE(g_ClrResumeEvent.IsValid());
- g_ClrResumeEvent.Set();
-
- return S_OK;
-}
-
-
-
-CorExecutionManager::CorExecutionManager()
- : m_dwFlags(0), m_pauseStartTime(0)
-{
- LIMITED_METHOD_CONTRACT;
- g_IsPaused = FALSE;
- g_PauseTime = 0;
-}
-
-HRESULT CorExecutionManager::Pause(DWORD dwAppDomainId, DWORD dwFlags)
-{
- CONTRACTL
- {
- NOTHROW;
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- ENTRY_POINT; // This is called by a host.
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
-#ifndef FEATURE_CORECLR
- if (!IsRuntimeActive())
- return HOST_E_CLRNOTAVAILABLE;
-#endif
-
- if(g_IsPaused)
- return E_FAIL;
-
- EX_TRY
- {
- if(!g_ClrResumeEvent.IsValid())
- g_ClrResumeEvent.CreateManualEvent(FALSE);
- else
- g_ClrResumeEvent.Reset();
-
-#ifndef FEATURE_CORECLR
- if (!g_PauseCompletedEvent.IsValid())
- g_PauseCompletedEvent.CreateManualEvent(FALSE);
- else
- g_PauseCompletedEvent.Reset();
-#endif
- }
- EX_CATCH_HRESULT(hr);
-
- if (FAILED(hr))
- return hr;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- m_dwFlags = dwFlags;
-
-#ifndef FEATURE_CORECLR
- if ((m_dwFlags & PAUSE_APP_DOMAINS) != 0)
- {
- Thread* pThread = SetupThreadNoThrow(&hr);
- if (pThread != NULL)
- {
- GCX_COOP_THREAD_EXISTS(pThread);
-
- AppDomainIterator ai(/*bOnlyActive:*/ TRUE);
- while (ai.Next())
- PauseOneAppDomain(&ai);
- }
- }
-#endif
-
- if (SUCCEEDED(hr))
- {
- g_IsPaused = TRUE;
-
- hr = SuspendEEForPause();
-
- // Even though this is named with TickCount, it returns milliseconds
- m_pauseStartTime = (INT64)CLRGetTickCount64();
- }
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-
-HRESULT CorExecutionManager::Resume(DWORD dwAppDomainId)
-{
- CONTRACTL
- {
- NOTHROW;
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- ENTRY_POINT; // This is called by a host.
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
-#ifndef FEATURE_CORECLR
- if (!IsRuntimeActive())
- return HOST_E_CLRNOTAVAILABLE;
-#endif
-
- if(!g_IsPaused)
- return E_FAIL;
-
-#ifdef FEATURE_CORECLR
- // GCThread is the thread that did the Pause. Resume should also happen on that same thread
- Thread *pThread = GetThread();
- if(pThread != ThreadSuspend::GetSuspensionThread())
- {
- _ASSERTE(!"HOST BUG: The same thread that did Pause should do the Resume");
- return E_FAIL;
- }
-#endif
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- // Even though this is named with TickCount, it returns milliseconds
- INT64 currTime = (INT64)CLRGetTickCount64();
- _ASSERTE(currTime >= m_pauseStartTime);
- _ASSERTE(m_pauseStartTime != 0);
-
- g_PauseTime += (currTime - m_pauseStartTime);
- g_IsPaused = FALSE;
-
- hr = RestartEEFromPauseAndSetResumeEvent();
-
-#ifndef FEATURE_CORECLR
- if (SUCCEEDED(hr))
- {
- if ((m_dwFlags & PAUSE_APP_DOMAINS) != 0)
- {
- Thread* pThread = SetupThreadNoThrow(&hr);
- if (pThread != NULL)
- {
- GCX_COOP_THREAD_EXISTS(pThread);
-
- AppDomainIterator ai(/*bOnlyActive:*/ TRUE);
- while (ai.Next())
- ResumeOneAppDomain(&ai);
- }
- }
- }
-#endif
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-
-#endif //!DACCESS_COMPILE
-
-#ifdef FEATURE_CORECLR
-#ifndef DACCESS_COMPILE
-SVAL_IMPL(STARTUP_FLAGS, CorHost2, m_dwStartupFlags = STARTUP_CONCURRENT_GC);
-#else
-SVAL_IMPL(STARTUP_FLAGS, CorHost2, m_dwStartupFlags);
-#endif
-
-STARTUP_FLAGS CorHost2::GetStartupFlags()
-{
- return m_dwStartupFlags;
-}
-#endif //FEATURE_CORECLR
-
-#ifndef DACCESS_COMPILE
-
-#if !defined(FEATURE_CORECLR)
-/*************************************************************************************
- ** ICLRPrivRuntime Methods
- *************************************************************************************/
-
-HRESULT CorHost2::GetInterface(
- REFCLSID rclsid,
- REFIID riid,
- LPVOID * ppUnk)
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- EX_TRY
- {
- if (rclsid == __uuidof(CLRPrivAppXBinder))
- {
- CLRPrivBinderAppX * pBinder = CLRPrivBinderAppX::GetOrCreateBinder();
- hr = pBinder->QueryInterface(riid, ppUnk);
- }
- else
- {
- hr = E_NOINTERFACE;
- }
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-
-HRESULT CorHost2::CreateAppDomain(
- LPCWSTR pwzFriendlyName,
- ICLRPrivBinder * pBinder,
- LPDWORD pdwAppDomainId)
-{
- return _CreateAppDomain(
- pwzFriendlyName,
- 0 /* default security */,
- nullptr, /* domain manager */
- nullptr, /* domain manager */
- 0, /* property count */
- nullptr, /* property names */
- nullptr, /* property values */
- pBinder,
- pdwAppDomainId);
-}
-
-HRESULT CorHost2::CreateDelegate(
- DWORD appDomainID,
- LPCWSTR wszAssemblyName,
- LPCWSTR wszClassName,
- LPCWSTR wszMethodName,
- LPVOID * ppvDelegate)
-{
- return _CreateDelegate(appDomainID, wszAssemblyName, wszClassName,
- wszMethodName, reinterpret_cast<INT_PTR*>(ppvDelegate));
-}
-
-// Flag indicating if the EE was started up by an managed exe. Defined in ceemain.cpp.
-extern BOOL g_fEEManagedEXEStartup;
-
-HRESULT CorHost2::ExecuteMain(
- ICLRPrivBinder * pBinder,
- int * pRetVal)
-{
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_ENTRY_POINT;
-
- HRESULT hr = S_OK;
-
- // If an exception passes through here, it will cause the
- // "The application has generated an unhandled exception" dialog and offer to debug.
- BEGIN_ENTRYPOINT_THROWS;
-
- // Indicates that the EE was started up by a managed exe.
- g_fEEManagedEXEStartup = TRUE;
-
- IfFailGo(CorCommandLine::SetArgvW(WszGetCommandLine()));
-
- IfFailGo(EnsureEEStarted(COINITEE_MAIN));
-
- INSTALL_UNWIND_AND_CONTINUE_HANDLER;
-
- //
- // Look for the [STAThread] or [MTAThread] attribute
- // TODO delete this code when we move to the default AppDomain
- //
- HMODULE hMod = WszGetModuleHandle(NULL);
-
- PEImageHolder pTempImage(PEImage::LoadImage(hMod));
- PEFileHolder pTempFile(PEFile::Open(pTempImage.Extract()));
-
- // Check for CustomAttributes - Set up the DefaultDomain and the main thread
- // Note that this has to be done before ExplicitBind() as it
- // affects the bind
- mdToken tkEntryPoint = pTempFile->GetEntryPointToken();
- // <TODO>@TODO: What if the entrypoint is in another file of the assembly?</TODO>
- ReleaseHolder<IMDInternalImport> scope(pTempFile->GetMDImportWithRef());
- // In theory, we should have a valid executable image and scope should never be NULL, but we've been
- // getting Watson failures for AVs here due to ISVs modifying image headers and some new OS loader
- // checks (see Dev10# 718530 and Windows 7# 615596)
- if (scope == NULL)
- {
- ThrowHR(COR_E_BADIMAGEFORMAT);
- }
-
- Thread::ApartmentState state = Thread::AS_Unknown;
-
- if((!IsNilToken(tkEntryPoint)) && (TypeFromToken(tkEntryPoint) == mdtMethodDef)) {
- if (scope->IsValidToken(tkEntryPoint))
- state = SystemDomain::GetEntryPointThreadAptState(scope, tkEntryPoint);
- else
- ThrowHR(COR_E_BADIMAGEFORMAT);
- }
-
- BOOL fSetGlobalSharePolicyUsingAttribute = FALSE;
-
- if((!IsNilToken(tkEntryPoint)) && (TypeFromToken(tkEntryPoint) == mdtMethodDef))
- {
- // The global share policy needs to be set before initializing default domain
- // so that it is in place for loading of appdomain manager.
- fSetGlobalSharePolicyUsingAttribute = SystemDomain::SetGlobalSharePolicyUsingAttribute(scope, tkEntryPoint);
- }
-
- // If the entry point has an explicit thread apartment state, set it
- // before running the AppDomainManager initialization code.
- if (state == Thread::AS_InSTA || state == Thread::AS_InMTA)
- SystemDomain::SetThreadAptState(scope, state);
-
- // This can potentially run managed code.
- SystemDomain::InitializeDefaultDomain(FALSE, pBinder);
-
- // If we haven't set an explicit thread apartment state, set it after the
- // AppDomainManager has got a chance to go set it in InitializeNewDomain.
- if (state != Thread::AS_InSTA && state != Thread::AS_InMTA)
- SystemDomain::SetThreadAptState(scope, state);
-
- if (fSetGlobalSharePolicyUsingAttribute)
- SystemDomain::System()->DefaultDomain()->SetupLoaderOptimization(g_dwGlobalSharePolicy);
-
- ADID adId(DefaultADID);
-
- GCX_COOP();
-
- ENTER_DOMAIN_ID(adId)
- TESTHOOKCALL(EnteredAppDomain(adId.m_dwId));
- {
- GCX_PREEMP();
-
- AppDomain *pDomain = GetAppDomain();
- _ASSERTE(pDomain);
-
- PathString wzExeFileName;
-
- if (WszGetModuleFileName(nullptr, wzExeFileName) == 0)
- IfFailThrow(E_UNEXPECTED);
-
- LPWSTR wzExeSimpleFileName = nullptr;
- size_t cchExeSimpleFileName = 0;
- SplitPathInterior(
- wzExeFileName,
- nullptr, nullptr, // drive
- nullptr, nullptr, // dir
- (LPCWSTR*)&wzExeSimpleFileName, &cchExeSimpleFileName, // filename
- nullptr, nullptr); // ext
-
- // Remove the extension
- wzExeSimpleFileName[cchExeSimpleFileName] = W('\0');
-
- ReleaseHolder<IAssemblyName> pAssemblyName;
- IfFailThrow(CreateAssemblyNameObject(
- &pAssemblyName, // Returned IAssemblyName
- wzExeSimpleFileName, // Name of assembly
- CANOF_PARSE_DISPLAY_NAME, // Parse as display name
- nullptr)); // Reserved
-
- AssemblySpec specExe;
- specExe.InitializeSpec(pAssemblyName, nullptr, false);
-
- PEAssemblyHolder pPEAssembly = pDomain->BindAssemblySpec(&specExe, TRUE, FALSE);
-
- pDomain->SetRootAssembly(pDomain->LoadAssembly(NULL, pPEAssembly, FILE_ACTIVE));
-
- LOG((LF_CLASSLOADER | LF_CORDB,
- LL_INFO10,
- "Created domain for an executable at %p\n",
- (pDomain->GetRootAssembly()? pDomain->GetRootAssembly()->Parent() : NULL)));
- TESTHOOKCALL(RuntimeStarted(RTS_CALLINGENTRYPOINT));
-
- // Set the friendly name to indicate that this is an immersive domain.
- pDomain->SetFriendlyName(W("Immersive Application Domain"), TRUE);
-
- // Execute the main method
- // NOTE: we call the entry point with our entry point exception filter active
- // after the AppDomain transition which is a bit different from classic apps.
- // this is so that we have the correct context when notifying the debugger
- // or invoking WER on the main thread and mimics the behavior of classic apps.
- // the assumption is that AppX entry points are always invoked post-AD transition.
- ExecuteMainInner(pDomain->GetRootAssembly());
-
- // Get the global latched exit code instead of the return value from ExecuteMainMethod
- // because in the case of a "void Main" method the return code is always 0,
- // while the latched exit code is set in either case.
- *pRetVal = GetLatchedExitCode();
- }
- END_DOMAIN_TRANSITION;
- TESTHOOKCALL(LeftAppDomain(adId.m_dwId));
-
- UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
-
-ErrExit:
- END_ENTRYPOINT_THROWS;
-
- return hr;
-}
-
-VOID CorHost2::ExecuteMainInner(Assembly* pRootAssembly)
-{
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_ENTRY_POINT;
-
- struct Param
- {
- Assembly* pRootAssembly;
- } param;
-
- param.pRootAssembly = pRootAssembly;
-
- PAL_TRY(Param*, pParam, ¶m)
- {
- // since this is the thread 0 entry point for AppX apps we use
- // the EntryPointFilter so that an unhandled exception here will
- // trigger the same behavior as in classic apps.
- pParam->pRootAssembly->ExecuteMainMethod(NULL, TRUE /* waitForOtherThreads */);
- }
- PAL_EXCEPT_FILTER(EntryPointFilter)
- {
- LOG((LF_STARTUP, LL_INFO10, "EntryPointFilter returned EXCEPTION_EXECUTE_HANDLER!"));
- }
- PAL_ENDTRY
-}
-
-// static
-HRESULT CorHost2::SetFlagsAndHostConfig(STARTUP_FLAGS dwStartupFlags, LPCWSTR pwzHostConfigFile, BOOL fFinalize)
-{
- WRAPPER_NO_CONTRACT;
-
- HRESULT hr = E_INVALIDARG;
-
- if (pwzHostConfigFile == NULL)
- pwzHostConfigFile = W("");
-
- DangerousNonHostedSpinLockHolder lockHolder(&m_FlagsLock);
-
- if (m_dwFlagsFinalized)
- {
- // verify that flags and config file are the same
- if (dwStartupFlags == m_dwStartupFlags &&
- _wcsicmp(pwzHostConfigFile, m_wzHostConfigFile) == 0)
- {
- hr = S_OK;
- }
- }
- else
- {
- // overwrite the flags and config with the incoming values
- if (wcslen(pwzHostConfigFile) < COUNTOF(m_wzHostConfigFile))
- {
- VERIFY(wcscpy_s(m_wzHostConfigFile, COUNTOF(m_wzHostConfigFile), pwzHostConfigFile) == 0);
-
- // If they asked for the server gc but only have one processor, deny that option.
- // Keep this in sync with shim logic in ComputeStartupFlagsAndFlavor that also switches to
- // the workstation GC on uniprocessor boxes.
- if (g_SystemInfo.dwNumberOfProcessors == 1 && (dwStartupFlags & STARTUP_SERVER_GC))
- dwStartupFlags = (STARTUP_FLAGS)(dwStartupFlags & ~(STARTUP_SERVER_GC | STARTUP_CONCURRENT_GC));
-
- m_dwStartupFlags = dwStartupFlags;
-
- if (fFinalize)
- m_dwFlagsFinalized = TRUE;
-
- hr = S_OK;
- }
- }
-
- return hr;
-}
-
-// static
-STARTUP_FLAGS CorHost2::GetStartupFlags()
-{
- WRAPPER_NO_CONTRACT;
-
- if (!m_dwFlagsFinalized) // make sure we return consistent results
- {
- DangerousNonHostedSpinLockHolder lockHolder(&m_FlagsLock);
- m_dwFlagsFinalized = TRUE;
- }
-
- return m_dwStartupFlags;
-}
-
-// static
-LPCWSTR CorHost2::GetHostConfigFile()
-{
- WRAPPER_NO_CONTRACT;
-
- if (!m_dwFlagsFinalized) // make sure we return consistent results
- {
- DangerousNonHostedSpinLockHolder lockHolder(&m_FlagsLock);
- m_dwFlagsFinalized = TRUE;
- }
-
- return m_wzHostConfigFile;
-}
-
-// static
-void CorHost2::GetDefaultAppDomainProperties(StringArrayList **pPropertyNames, StringArrayList **pPropertyValues)
-{
- LIMITED_METHOD_CONTRACT;
-
- // We should only read these after the runtime has started to ensure that the host isn't modifying them
- // still
- _ASSERTE(g_fEEStarted || HasStarted());
-
- *pPropertyNames = &s_defaultDomainPropertyNames;
- *pPropertyValues = &s_defaultDomainPropertyValues;
-}
-
-#endif // !FEATURE_CORECLR
-
-#ifdef FEATURE_COMINTEROP
-
-// Enumerate currently existing domains.
-HRESULT CorRuntimeHostBase::EnumDomains(HDOMAINENUM *hEnum)
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_PREEMPTIVE;
- WRAPPER(GC_TRIGGERS);
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- if(hEnum == NULL) return E_POINTER;
-
- // Thread setup happens in BEGIN_EXTERNAL_ENTRYPOINT below.
- // If the runtime has not started, we have nothing to do.
- if (!g_fEEStarted)
- {
- return HOST_E_CLRNOTAVAILABLE;
- }
-
- HRESULT hr = E_OUTOFMEMORY;
- *hEnum = NULL;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr)
-
- AppDomainIterator *pEnum = new (nothrow) AppDomainIterator(FALSE);
- if(pEnum) {
- *hEnum = (HDOMAINENUM) pEnum;
- hr = S_OK;
- }
- END_EXTERNAL_ENTRYPOINT;
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-#endif // FEATURE_COMINTEROP
-
-extern "C"
-HRESULT GetCLRRuntimeHost(REFIID riid, IUnknown **ppUnk)
-{
- WRAPPER_NO_CONTRACT;
-
- return CorHost2::CreateObject(riid, (void**)ppUnk);
-}
-
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
-
-HRESULT NextDomainWorker(AppDomainIterator *pEnum,
- IUnknown** pAppDomain)
-{
- CONTRACTL
- {
- DISABLED(NOTHROW); // nothrow contract's fs:0 handler gets called before the C++ EH fs:0 handler which is pushed in the prolog
- GC_TRIGGERS;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- Thread *pThread = GetThread();
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(pThread, return COR_E_STACKOVERFLOW);
-
- EX_TRY
- {
- GCX_COOP_THREAD_EXISTS(pThread);
-
- if (pEnum->Next())
- {
- AppDomain* pDomain = pEnum->GetDomain();
- // Need to enter the AppDomain to synchronize access to the exposed
- // object properly (can't just take the system domain mutex since we
- // might need to run code that uses higher ranking crsts).
- ENTER_DOMAIN_PTR(pDomain,ADV_ITERATOR)
- {
-
- hr = pDomain->GetComIPForExposedObject(pAppDomain);
- }
- END_DOMAIN_TRANSITION;
- }
- else
- {
- hr = S_FALSE;
- }
- }
- EX_CATCH_HRESULT(hr);
-
- END_SO_INTOLERANT_CODE;
-
- return hr;
-}
-
-// Returns S_FALSE when there are no more domains. A domain
-// is passed out only when S_OK is returned.
-HRESULT CorRuntimeHostBase::NextDomain(HDOMAINENUM hEnum,
- IUnknown** pAppDomain)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- if(hEnum == NULL || pAppDomain == NULL)
- return E_POINTER;
-
- // If the runtime has not started, we have nothing to do.
- if (!g_fEEStarted)
- {
- return HOST_E_CLRNOTAVAILABLE;
- }
-
- HRESULT hr;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- AppDomainIterator *pEnum = (AppDomainIterator *) hEnum;
-
- do
- {
- hr = NextDomainWorker(pEnum, pAppDomain);
- // Might need to look at the next appdomain if we were attempting to get at
- // the exposed appdomain object and were chucked out as the result of an
- // appdomain unload.
- } while (hr == COR_E_APPDOMAINUNLOADED);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-// Creates a domain in the runtime. The identity array is
-// a pointer to an array TYPE containing IIdentity objects defining
-// the security identity.
-HRESULT CorRuntimeHostBase::CreateDomainEx(LPCWSTR pwzFriendlyName,
- IUnknown* pSetup, // Optional
- IUnknown* pEvidence, // Optional
- IUnknown ** pAppDomain)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- if(!pwzFriendlyName) return E_POINTER;
- if(pAppDomain == NULL) return E_POINTER;
- if(!g_fEEStarted) return E_FAIL;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr);
- {
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
-
- struct _gc {
- STRINGREF pName;
- OBJECTREF pSetup;
- OBJECTREF pEvidence;
- APPDOMAINREF pDomain;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- if (FAILED(hr = EnsureComStartedNoThrow()))
- goto lDone;
-
- GCPROTECT_BEGIN(gc);
-
- gc.pName = StringObject::NewString(pwzFriendlyName);
-
- if(pSetup)
- GetObjectRefFromComIP(&gc.pSetup, pSetup);
- if(pEvidence)
- GetObjectRefFromComIP(&gc.pEvidence, pEvidence);
-
- MethodDescCallSite createDomain(METHOD__APP_DOMAIN__CREATE_DOMAIN);
-
- ARG_SLOT args[3] = {
- ObjToArgSlot(gc.pName),
- ObjToArgSlot(gc.pEvidence),
- ObjToArgSlot(gc.pSetup),
- };
-
- gc.pDomain = (APPDOMAINREF) createDomain.Call_RetOBJECTREF(args);
-
- *pAppDomain = GetComIPFromObjectRef((OBJECTREF*) &gc.pDomain);
-
- GCPROTECT_END();
-
-lDone: ;
- }
- END_EXTERNAL_ENTRYPOINT;
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-// Close the enumeration releasing resources
-HRESULT CorRuntimeHostBase::CloseEnum(HDOMAINENUM hEnum)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- if(hEnum) {
- AppDomainIterator* pEnum = (AppDomainIterator*) hEnum;
- delete pEnum;
- }
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-
-HRESULT CorRuntimeHostBase::CreateDomainSetup(IUnknown **pAppDomainSetup)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- ENTRY_POINT;
- MODE_PREEMPTIVE;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- if (!pAppDomainSetup)
- return E_POINTER;
-
- // If the runtime has not started, we have nothing to do.
- if (!g_fEEStarted)
- {
- return HOST_E_CLRNOTAVAILABLE;
- }
-
- // Create the domain.
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr);
- {
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
-
- struct _gc {
- OBJECTREF pSetup;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
- MethodTable* pMT = NULL;
-
- hr = EnsureComStartedNoThrow();
- if (FAILED(hr))
- goto lDone;
-
- pMT = MscorlibBinder::GetClass(CLASS__APPDOMAIN_SETUP);
-
- GCPROTECT_BEGIN(gc);
- gc.pSetup = AllocateObject(pMT);
- *pAppDomainSetup = GetComIPFromObjectRef((OBJECTREF*) &gc.pSetup);
- GCPROTECT_END();
-
-lDone: ;
- }
- END_EXTERNAL_ENTRYPOINT;
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-HRESULT CorRuntimeHostBase::CreateEvidence(IUnknown **pEvidence)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- if (!pEvidence)
- return E_POINTER;
-
-#ifdef FEATURE_CAS_POLICY
-
- // If the runtime has not started, we have nothing to do.
- if (!g_fEEStarted)
- {
- return HOST_E_CLRNOTAVAILABLE;
- }
-
- // Create the domain.
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr);
- {
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
-
- struct _gc {
- OBJECTREF pEvidence;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- MethodTable* pMT = NULL;
-
- hr = EnsureComStartedNoThrow();
- if (FAILED(hr))
- goto lDone;
-
- pMT = MscorlibBinder::GetClass(CLASS__EVIDENCE);
-
- GCPROTECT_BEGIN(gc);
- gc.pEvidence = AllocateObject(pMT);
- MethodDescCallSite ctor(METHOD__EVIDENCE__CTOR, &(gc.pEvidence));
-
- // Call the Evidence class constructor.
- ARG_SLOT CtorArgs[] =
- {
- ObjToArgSlot(gc.pEvidence)
- };
- ctor.Call(CtorArgs);
-
- *pEvidence = GetComIPFromObjectRef((OBJECTREF*) &gc.pEvidence);
- GCPROTECT_END();
-
-lDone: ;
- }
- END_EXTERNAL_ENTRYPOINT;
- END_ENTRYPOINT_NOTHROW;
-#else // !FEATURE_CAS_POLICY
- // There is no Evidence class support without CAS policy.
- return E_NOTIMPL;
-#endif // FEATURE_CAS_POLICY
-
- return hr;
-}
-
-HRESULT CorRuntimeHostBase::UnloadDomain(IUnknown *pUnkDomain)
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- FORBID_FAULT;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- if (!pUnkDomain)
- return E_POINTER;
-
- // If the runtime has not started, we have nothing to do.
- if (!g_fEEStarted)
- {
- return HOST_E_CLRNOTAVAILABLE;
- }
-
- CONTRACT_VIOLATION(FaultViolation); // This entire function is full of OOM potential: must fix.
-
- HRESULT hr = S_OK;
- DWORD dwDomainId = 0;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- _ASSERTE (g_fComStarted);
-
- {
- SystemDomain::LockHolder lh;
-
- ComCallWrapper* pWrap = GetCCWFromIUnknown(pUnkDomain, FALSE);
- if (!pWrap)
- {
- hr = COR_E_APPDOMAINUNLOADED;
- }
- if (SUCCEEDED(hr))
- {
- dwDomainId = pWrap->GetDomainID().m_dwId;
- }
- }
- if (SUCCEEDED(hr))
- {
- hr = UnloadAppDomain(dwDomainId, TRUE);
- }
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-#endif // FEATURE_COMINTEROP && !FEATURE_CORECLR
-
-STDMETHODIMP CorHost2::UnloadAppDomain(DWORD dwDomainId, BOOL fWaitUntilDone)
-{
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
-
-#ifdef FEATURE_CORECLR
- if (!m_fStarted)
- return HOST_E_INVALIDOPERATION;
-
- if(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN)
- {
- if (!g_fEEStarted)
- {
- return HOST_E_CLRNOTAVAILABLE;
- }
-
- if(!m_fAppDomainCreated)
- {
- return HOST_E_INVALIDOPERATION;
- }
-
- HRESULT hr=S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- if (!m_fFirstToLoadCLR)
- {
- _ASSERTE(!"Not reachable");
- hr = HOST_E_CLRNOTAVAILABLE;
- }
- else
- {
- LONG refCount = m_RefCount;
- if (refCount == 0)
- {
- hr = HOST_E_CLRNOTAVAILABLE;
- }
- else
- if (1 == refCount)
- {
- // Stop coreclr on unload.
- m_fStarted = FALSE;
- EEShutDown(FALSE);
- }
- else
- {
- _ASSERTE(!"Not reachable");
- hr = S_FALSE;
- }
- }
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
- }
- else
-#endif // FEATURE_CORECLR
-
- return CorRuntimeHostBase::UnloadAppDomain(dwDomainId, fWaitUntilDone);
-}
-
-HRESULT CorRuntimeHostBase::UnloadAppDomain(DWORD dwDomainId, BOOL fSync)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- FORBID_FAULT; // Unloading domains cannot fail due to OOM
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // No point going further if the runtime is not running...
- {
- // In IsRuntimeActive, we will call CanRunManagedCode that will
- // check if the current thread has taken the loader lock or not,
- // if MDA is supported. To do the check, MdaLoaderLock::ReportViolation
- // will be invoked that will internally end up invoking
- // MdaFactory<MdaXmlElement>::GetNext that will use the "new" operator
- // that has the "FAULT" contract set, resulting in FAULT_VIOLATION since
- // this method has the FORBID_FAULT contract set above.
- //
- // However, for a thread that holds the loader lock, unloading the appDomain is
- // not a supported scenario. Thus, we should not be ending up in this code
- // path for the FAULT violation.
- //
- // Hence, the CONTRACT_VIOLATION below for overriding the FORBID_FAULT
- // for this scope only.
- CONTRACT_VIOLATION(FaultViolation);
- if (!IsRuntimeActive()
- #ifdef FEATURE_CORECLR
- || !m_fStarted
- #endif // FEATURE_CORECLR
- )
- {
- return HOST_E_CLRNOTAVAILABLE;
- }
- }
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- // We do not use BEGIN_EXTERNAL_ENTRYPOINT here because
- // we do not want to setup Thread. Process may be OOM, and we want Unload
- // to work.
- hr = AppDomain::UnloadById(ADID(dwDomainId), fSync);
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-//*****************************************************************************
-// Fiber Methods
-//*****************************************************************************
-#if !defined(FEATURE_CORECLR) // simple hosting
-HRESULT CorHost::CreateLogicalThreadState()
-{
- CONTRACTL
- {
- NOTHROW;
- DISABLED(GC_TRIGGERS);
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
- if (CorHost::GetHostVersion() != 1)
- {
- hr=HOST_E_INVALIDOPERATION;
- }
- else
- {
- _ASSERTE (GetThread() == 0 || GetThread()->HasRightCacheStackBase());
- /* Thread *thread = */ SetupThreadNoThrow(&hr);
-
- }
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-
-HRESULT CorHost::DeleteLogicalThreadState()
-{
- if (CorHost::GetHostVersion() != 1)
- {
- return HOST_E_INVALIDOPERATION;
- }
-
- Thread *pThread = GetThread();
- if (!pThread)
- return E_UNEXPECTED;
-
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- ENTRY_POINT;
- }
- CONTRACTL_END;
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
- // We need to reset the TrapReturningThread count that was
- // set when a thread is requested to be aborted. Otherwise
- // every stub call is going to go through a slow path.
- if (pThread->IsAbortRequested())
- pThread->UnmarkThreadForAbort(Thread::TAR_ALL);
-
- // see code:Thread::OnThreadTerminate#ReportDeadOnThreadTerminate
- pThread->SetThreadState(Thread::TS_ReportDead);
-
- pThread->OnThreadTerminate(FALSE);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-
-HRESULT CorHost::SwitchInLogicalThreadState(DWORD *pFiberCookie)
-{
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_NOTRIGGER;
- STATIC_CONTRACT_MODE_ANY;
- STATIC_CONTRACT_ENTRY_POINT;
-
- if (CorHost::GetHostVersion() != 1)
- {
- return HOST_E_INVALIDOPERATION;
- }
-
- if (!pFiberCookie)
- {
- return E_POINTER;
- }
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- hr = ((Thread*)pFiberCookie)->SwitchIn(::GetCurrentThread());
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
-
-}
-
-HRESULT CorHost::SwitchOutLogicalThreadState(DWORD **pFiberCookie)
-{
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_NOTRIGGER;
- STATIC_CONTRACT_MODE_ANY;
- STATIC_CONTRACT_ENTRY_POINT;
-
- if (CorHost::GetHostVersion() != 1)
- {
- return HOST_E_INVALIDOPERATION;
- }
-
- if (!pFiberCookie)
- {
- return E_POINTER;
- }
-
- Thread *pThread = GetThread();
- if (!pThread)
- {
- return E_UNEXPECTED;
- }
-
- pThread->InternalSwitchOut();
- *pFiberCookie = (DWORD*)pThread;
-
- return S_OK;
-}
-#endif // !defined(FEATURE_CORECLR)
-
-HRESULT CorRuntimeHostBase::LocksHeldByLogicalThread(DWORD *pCount)
-{
- if (!pCount)
- return E_POINTER;
-
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- Thread* pThread = GetThread();
- if (pThread == NULL)
- *pCount = 0;
- else
- *pCount = pThread->m_dwLockCount;
-
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
-}
-
-//*****************************************************************************
-// ICorConfiguration
-//*****************************************************************************
-#if !defined(FEATURE_CORECLR)
-IGCThreadControl *CorConfiguration::m_CachedGCThreadControl = 0;
-IGCHostControl *CorConfiguration::m_CachedGCHostControl = 0;
-IDebuggerThreadControl *CorConfiguration::m_CachedDebuggerThreadControl = 0;
-DWORD *CorConfiguration::m_DSTArray = 0;
-DWORD CorConfiguration::m_DSTCount = 0;
-DWORD CorConfiguration::m_DSTArraySize = 0;
-
-// *** ICorConfiguration methods ***
-
-
-HRESULT CorConfiguration::SetGCThreadControl(IGCThreadControl *pGCThreadControl)
-{
- if (!pGCThreadControl)
- return E_POINTER;
-
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- if (m_CachedGCThreadControl)
- m_CachedGCThreadControl->Release();
-
- m_CachedGCThreadControl = pGCThreadControl;
-
- if (m_CachedGCThreadControl)
- m_CachedGCThreadControl->AddRef();
-
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
-}
-
-HRESULT CorConfiguration::SetGCHostControl(IGCHostControl *pGCHostControl)
-{
- if (!pGCHostControl)
- return E_POINTER;
-
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- if (m_CachedGCHostControl)
- m_CachedGCHostControl->Release();
-
- m_CachedGCHostControl = pGCHostControl;
-
- if (m_CachedGCHostControl)
- m_CachedGCHostControl->AddRef();
-
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
-}
-
-HRESULT CorConfiguration::SetDebuggerThreadControl(IDebuggerThreadControl *pDebuggerThreadControl)
-{
- if (!pDebuggerThreadControl)
- return E_POINTER;
-
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
-#ifdef DEBUGGING_SUPPORTED
- // Can't change the debugger thread control object once its been set.
- if (m_CachedDebuggerThreadControl != NULL)
- IfFailGo(E_INVALIDARG);
-
- m_CachedDebuggerThreadControl = pDebuggerThreadControl;
-
- // If debugging is already initialized then provide this interface pointer to it.
- // It will also addref the new one and release the old one.
- if (g_pDebugInterface)
- g_pDebugInterface->SetIDbgThreadControl(pDebuggerThreadControl);
-
- if (m_CachedDebuggerThreadControl)
- m_CachedDebuggerThreadControl->AddRef();
-
- hr = S_OK;
-#else // !DEBUGGING_SUPPORTED
- hr = E_NOTIMPL;
-#endif // !DEBUGGING_SUPPORTED
-
-ErrExit:
- END_ENTRYPOINT_NOTHROW;
- return hr;
-
-}
-
-
-HRESULT CorConfiguration::AddDebuggerSpecialThread(DWORD dwSpecialThreadId)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT; // debugging not hardened for SO
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
-
-#ifdef DEBUGGING_SUPPORTED
- // If it's already in the list, don't add it again.
- if (IsDebuggerSpecialThread(dwSpecialThreadId))
- {
- hr = S_OK;
- goto ErrExit;
- }
- // Grow the array if necessary.
- if (m_DSTCount >= m_DSTArraySize)
- {
- // There's probably only ever gonna be one or two of these
- // things, so we'll start small.
- DWORD newSize = (m_DSTArraySize == 0) ? 2 : m_DSTArraySize * 2;
-
- DWORD *newArray = new (nothrow) DWORD[newSize];
- IfNullGo(newArray);
-
- // If we're growing instead of starting, then copy the old array.
- if (m_DSTArray)
- {
- memcpy(newArray, m_DSTArray, m_DSTArraySize * sizeof(DWORD));
- delete [] m_DSTArray;
- }
-
- // Update to the new array and size.
- m_DSTArray = newArray;
- m_DSTArraySize = newSize;
- }
-
- // Save the new thread ID.
- m_DSTArray[m_DSTCount++] = dwSpecialThreadId;
-
- hr = (RefreshDebuggerSpecialThreadList());
-#else // !DEBUGGING_SUPPORTED
- hr = E_NOTIMPL;
-#endif // !DEBUGGING_SUPPORTED
-ErrExit:
- END_ENTRYPOINT_NOTHROW;
- return hr;
-
-}
-// Helper function to update the thread list in the debugger control block
-HRESULT CorConfiguration::RefreshDebuggerSpecialThreadList()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
-#ifdef DEBUGGING_SUPPORTED
- HRESULT hr = S_OK;
-
- if (g_pDebugInterface)
- {
- // Inform the debugger services that this list has changed
- hr = g_pDebugInterface->UpdateSpecialThreadList(
- m_DSTCount, m_DSTArray);
-
- _ASSERTE(SUCCEEDED(hr));
- }
-
- return (hr);
-#else // !DEBUGGING_SUPPORTED
- return E_NOTIMPL;
-#endif // !DEBUGGING_SUPPORTED
-}
-
-
-// Helper func that returns true if the thread is in the debugger special thread list
-BOOL CorConfiguration::IsDebuggerSpecialThread(DWORD dwThreadId)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- for (DWORD i = 0; i < m_DSTCount; i++)
- {
- if (m_DSTArray[i] == dwThreadId)
- return (TRUE);
- }
-
- return (FALSE);
-}
-
-
-// Clean up any debugger thread control object we may be holding, called at shutdown.
-void CorConfiguration::CleanupDebuggerThreadControl()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- if (m_CachedDebuggerThreadControl != NULL)
- {
- // Note: we don't release the IDebuggerThreadControl object if we're cleaning up from
- // our DllMain. The DLL that implements the object may already have been unloaded.
- // Leaking the object is okay... the PDM doesn't care.
- if (!IsAtProcessExit())
- m_CachedDebuggerThreadControl->Release();
-
- m_CachedDebuggerThreadControl = NULL;
- }
-}
-#endif // !defined(FEATURE_CORECLR)
-
-//*****************************************************************************
-// IUnknown
-//*****************************************************************************
-
-ULONG CorRuntimeHostBase::AddRef()
-{
- CONTRACTL
- {
- WRAPPER(THROWS);
- WRAPPER(GC_TRIGGERS);
- SO_TOLERANT;
- }
- CONTRACTL_END;
- return InterlockedIncrement(&m_cRef);
-}
-
-#if !defined(FEATURE_CORECLR) // simple hosting
-ULONG CorHost::Release()
-{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
-
- ULONG cRef = InterlockedDecrement(&m_cRef);
- if (!cRef) {
- delete this;
- }
-
- return (cRef);
-}
-#endif // !defined(FEATURE_CORECLR)
-
-ULONG CorHost2::Release()
-{
- LIMITED_METHOD_CONTRACT;
-
- ULONG cRef = InterlockedDecrement(&m_cRef);
- if (!cRef) {
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- // CorHost2 is allocated before host memory interface is set up.
- if (GetHostMemoryManager() == NULL)
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- delete this;
- }
-
- return (cRef);
-}
-
-#if !defined(FEATURE_CORECLR) // simple hosting
-HRESULT CorHost::QueryInterface(REFIID riid, void **ppUnk)
-{
- if (!ppUnk)
- return E_POINTER;
-
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT; // no global state updates that need guarding.
- }
- CONTRACTL_END;
-
- if (ppUnk == NULL)
- {
- return E_POINTER;
- }
-
- *ppUnk = 0;
-
- // Deliberately do NOT hand out ICorConfiguration. They must explicitly call
- // GetConfiguration to obtain that interface.
- if (riid == IID_IUnknown)
- *ppUnk = (IUnknown *) (ICorRuntimeHost *) this;
- else if (riid == IID_ICorRuntimeHost)
- {
- ULONG version = 1;
- if (m_Version == 0)
- FastInterlockCompareExchange((LONG*)&m_Version, version, 0);
-
- if (m_Version != version && (g_singleVersionHosting || !g_fEEStarted))
- {
- return HOST_E_INVALIDOPERATION;
- }
-
- *ppUnk = (ICorRuntimeHost *) this;
- }
- else if (riid == IID_ICorThreadpool)
- *ppUnk = (ICorThreadpool *) this;
- else if (riid == IID_IGCHost)
- *ppUnk = (IGCHost *) this;
- else if (riid == IID_IGCHost2)
- *ppUnk = (IGCHost2 *) this;
- else if (riid == IID_IValidator)
- *ppUnk = (IValidator *) this;
- else if (riid == IID_IDebuggerInfo)
- *ppUnk = (IDebuggerInfo *) this;
- else if (riid == IID_ICLRExecutionManager)
- *ppUnk = (ICLRExecutionManager *) this;
- else
- return (E_NOINTERFACE);
- AddRef();
- return (S_OK);
-}
-#endif // !defined(FEATURE_CORECLR)
-
-
-HRESULT CorHost2::QueryInterface(REFIID riid, void **ppUnk)
-{
- if (!ppUnk)
- return E_POINTER;
-
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT; // no global state updates that need guarding.
- }
- CONTRACTL_END;
-
- if (ppUnk == NULL)
- {
- return E_POINTER;
- }
-
- *ppUnk = 0;
-
- // Deliberately do NOT hand out ICorConfiguration. They must explicitly call
- // GetConfiguration to obtain that interface.
- if (riid == IID_IUnknown)
- *ppUnk = static_cast<IUnknown *>(static_cast<ICLRRuntimeHost *>(this));
-#ifdef FEATURE_CORECLR // CoreCLR only supports IID_ICLRRuntimeHost2
- else if (riid == IID_ICLRRuntimeHost2)
- {
- ULONG version = 2;
- if (m_Version == 0)
- FastInterlockCompareExchange((LONG*)&m_Version, version, 0);
-
- *ppUnk = static_cast<ICLRRuntimeHost2 *>(this);
- }
-#else // DesktopCLR only supports IID_ICLRRuntimeHost
- else if (riid == IID_ICLRRuntimeHost)
- {
- ULONG version = 2;
- if (m_Version == 0)
- FastInterlockCompareExchange((LONG*)&m_Version, version, 0);
-
- *ppUnk = static_cast<ICLRRuntimeHost *>(this);
- }
-#endif // FEATURE_CORECLR
- else if (riid == IID_ICLRExecutionManager)
- {
- ULONG version = 2;
- if (m_Version == 0)
- FastInterlockCompareExchange((LONG*)&m_Version, version, 0);
-
- *ppUnk = static_cast<ICLRExecutionManager *>(this);
- }
-#if !defined(FEATURE_CORECLR)
- else if (riid == __uuidof(ICLRPrivRuntime))
- {
- ULONG version = 2;
- if (m_Version == 0)
- FastInterlockCompareExchange((LONG*)&m_Version, version, 0);
-
- *ppUnk = static_cast<ICLRPrivRuntime *>(this);
- }
-#endif
-#ifndef FEATURE_PAL
- else if (riid == IID_IPrivateManagedExceptionReporting)
- {
- *ppUnk = static_cast<IPrivateManagedExceptionReporting *>(this);
- }
-#endif // !FEATURE_PAL
-#ifndef FEATURE_CORECLR
- else if (riid == IID_ICorThreadpool)
- *ppUnk = static_cast<ICorThreadpool *>(this);
- // TODO: wwl Remove this after SQL uses new interface.
- else if (riid == IID_IGCHost &&
- GetHostVersion() == 3)
- *ppUnk = static_cast<IGCHost *>(this);
- else if (riid == IID_ICLRValidator)
- *ppUnk = static_cast<ICLRValidator *>(this);
- else if (riid == IID_IDebuggerInfo)
- *ppUnk = static_cast<IDebuggerInfo *>(this);
-#ifdef FEATURE_TESTHOOKS
- else if (riid == IID_ICLRTestHookManager)
- {
- *ppUnk=CLRTestHookManager::Start();
- if(*ppUnk==NULL)
- return E_OUTOFMEMORY;
- }
-#endif // FEATURE_TESTHOOKS
-#endif // FEATURE_CORECLR
- else
- return (E_NOINTERFACE);
- AddRef();
- return (S_OK);
-}
-
-#ifndef FEATURE_CORECLR // CorHost isn't exposed externally
-//*****************************************************************************
-// Called by the class factory template to create a new instance of this object.
-//*****************************************************************************
-HRESULT CorHost::CreateObject(REFIID riid, void **ppUnk)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- CorHost *pCorHost = new (nothrow) CorHost();
- if (!pCorHost)
- {
- hr = E_OUTOFMEMORY;
- }
- else
- {
- hr = pCorHost->QueryInterface(riid, ppUnk);
-
- if (FAILED(hr))
- delete pCorHost;
- }
- return (hr);
-}
-#endif // FEATURE_CORECLR
-
-#ifndef FEATURE_PAL
-HRESULT CorHost2::GetBucketParametersForCurrentException(BucketParameters *pParams)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- // To avoid confusion, clear the buckets.
- memset(pParams, 0, sizeof(BucketParameters));
-
- // Defer to Watson helper.
- hr = ::GetBucketParametersForCurrentException(pParams);
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-#endif // !FEATURE_PAL
-
-HRESULT CorHost2::CreateObject(REFIID riid, void **ppUnk)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW; );
- CorHost2 *pCorHost = new (nothrow) CorHost2();
- if (!pCorHost)
- {
- hr = E_OUTOFMEMORY;
- }
- else
- {
- hr = pCorHost->QueryInterface(riid, ppUnk);
- if (FAILED(hr))
- delete pCorHost;
- }
- END_SO_INTOLERANT_CODE;
- return (hr);
-}
-
-
-//-----------------------------------------------------------------------------
-// MapFile - Maps a file into the runtime in a non-standard way
-//-----------------------------------------------------------------------------
-
-static PEImage *MapFileHelper(HANDLE hFile)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- GCX_PREEMP();
-
- HandleHolder hFileMap(WszCreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL));
- if (hFileMap == NULL)
- ThrowLastError();
-
- CLRMapViewHolder base(CLRMapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0));
- if (base == NULL)
- ThrowLastError();
-
- DWORD dwSize = SafeGetFileSize(hFile, NULL);
- if (dwSize == 0xffffffff && GetLastError() != NOERROR)
- {
- ThrowLastError();
- }
- PEImageHolder pImage(PEImage::LoadFlat(base, dwSize));
- return pImage.Extract();
-}
-
-HRESULT CorRuntimeHostBase::MapFile(HANDLE hFile, HMODULE* phHandle)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr)
- {
- *phHandle = (HMODULE) (MapFileHelper(hFile)->GetLoadedLayout()->GetBase());
- }
- END_EXTERNAL_ENTRYPOINT;
- END_ENTRYPOINT_NOTHROW;
-
-
- return hr;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// IDebuggerInfo::IsDebuggerAttached
-#if !defined(FEATURE_CORECLR)
-HRESULT CorDebuggerInfo::IsDebuggerAttached(BOOL *pbAttached)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- if (pbAttached == NULL)
- hr = E_INVALIDARG;
- else
-#ifdef DEBUGGING_SUPPORTED
- *pbAttached = (CORDebuggerAttached() != 0);
-#else
- *pbAttached = FALSE;
-#endif
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-#endif // !defined(FEATURE_CORECLR)
-
-LONG CorHost2::m_RefCount = 0;
-
-IHostControl *CorHost2::m_HostControl = NULL;
-
-LPCWSTR CorHost2::s_wszAppDomainManagerAsm = NULL;
-LPCWSTR CorHost2::s_wszAppDomainManagerType = NULL;
-EInitializeNewDomainFlags CorHost2::s_dwDomainManagerInitFlags = eInitializeNewDomainFlags_None;
-
-#ifndef FEATURE_CORECLR // not supported
-
-StringArrayList CorHost2::s_defaultDomainPropertyNames;
-StringArrayList CorHost2::s_defaultDomainPropertyValues;
-
-IHostMemoryManager *CorHost2::m_HostMemoryManager = NULL;
-IHostMalloc *CorHost2::m_HostMalloc = NULL;
-IHostTaskManager *CorHost2::m_HostTaskManager = NULL;
-IHostThreadpoolManager *CorHost2::m_HostThreadpoolManager = NULL;
-IHostIoCompletionManager *CorHost2::m_HostIoCompletionManager = NULL;
-IHostSyncManager *CorHost2::m_HostSyncManager = NULL;
-IHostAssemblyManager *CorHost2::m_HostAssemblyManager = NULL;
-IHostGCManager *CorHost2::m_HostGCManager = NULL;
-IHostSecurityManager *CorHost2::m_HostSecurityManager = NULL;
-IHostPolicyManager *CorHost2::m_HostPolicyManager = NULL;
-int CorHost2::m_HostOverlappedExtensionSize = -1;
-
-STARTUP_FLAGS CorHost2::m_dwStartupFlags = STARTUP_CONCURRENT_GC;
-WCHAR CorHost2::m_wzHostConfigFile[_MAX_PATH] = { 0 };
-
-BOOL CorHost2::m_dwFlagsFinalized = FALSE;
-DangerousNonHostedSpinLock CorHost2::m_FlagsLock;
-
-class CCLRMemoryNotificationCallback: public ICLRMemoryNotificationCallback
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE OnMemoryNotification(EMemoryAvailable eMemoryAvailable) {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- // We have not started runtime yet.
- if (!g_fEEStarted)
- return S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- switch (eMemoryAvailable)
- {
- case eMemoryAvailableLow:
- STRESS_LOG0(LF_GC, LL_INFO100, "Host delivers memory notification: Low\n");
- break;
- case eMemoryAvailableNeutral:
- STRESS_LOG0(LF_GC, LL_INFO100, "Host delivers memory notification: Neutral\n");
- break;
- case eMemoryAvailableHigh:
- STRESS_LOG0(LF_GC, LL_INFO100, "Host delivers memory notification: High\n");
- break;
- }
- static DWORD lastTime = (DWORD)-1;
- if (eMemoryAvailable == eMemoryAvailableLow)
- {
- FastInterlockIncrement ((LONG *)&g_bLowMemoryFromHost);
- DWORD curTime = GetTickCount();
- if (curTime < lastTime || curTime - lastTime >= 0x2000)
- {
- lastTime = curTime;
- FinalizerThread::EnableFinalization();
- }
- }
- else
- {
- FastInterlockExchange ((LONG *)&g_bLowMemoryFromHost, FALSE);
- }
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
- }
-
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
- {
- LIMITED_METHOD_CONTRACT;
- if (riid != IID_ICLRMemoryNotificationCallback && riid != IID_IUnknown)
- return (E_NOINTERFACE);
- *ppvObject = this;
- return S_OK;
- }
-
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-};
-
-static CCLRMemoryNotificationCallback s_MemoryNotification;
-
-class CLRTaskManager : public ICLRTaskManager
-{
-public:
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) {
- LIMITED_METHOD_CONTRACT;
- if (riid != IID_ICLRTaskManager && riid != IID_IUnknown)
- return (E_NOINTERFACE);
- *ppvObject = this;
- return S_OK;
- }
-
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- virtual HRESULT STDMETHODCALLTYPE CreateTask(ICLRTask **pTask)
- {
- CONTRACTL
- {
- NOTHROW;
- DISABLED(GC_NOTRIGGER);
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
-#ifdef _DEBUG
- _ASSERTE (!CLRTaskHosted() || GetCurrentHostTask());
-#endif
- _ASSERTE (GetThread() == NULL);
- Thread *pThread = NULL;
- pThread = SetupThreadNoThrow(&hr);
- *pTask = pThread;
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
- }
-
- virtual HRESULT STDMETHODCALLTYPE GetCurrentTask(ICLRTask **pTask)
- {
- // This function may be called due SQL SwitchIn/Out. Contract may
- // force memory allocation which is not allowed during Switch.
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_NOTRIGGER;
- STATIC_CONTRACT_SO_TOLERANT;
- STATIC_CONTRACT_ENTRY_POINT;
-
- *pTask = GetThread();
- return S_OK;
- }
-
- virtual HRESULT STDMETHODCALLTYPE SetUILocale(LCID lcid)
- {
- Thread *pThread = GetThread();
- if (pThread == NULL)
- return HOST_E_INVALIDOPERATION;
-
- CONTRACTL
- {
- GC_TRIGGERS;
- NOTHROW;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- //BEGIN_ENTRYPOINT_NOTHROW;
- BEGIN_EXTERNAL_ENTRYPOINT(&hr)
- {
- pThread->SetCultureId(lcid,TRUE);
- }
- END_EXTERNAL_ENTRYPOINT;
- //END_ENTRYPOINT_NOTHROW;
-
- return hr;
- }
-
- virtual HRESULT STDMETHODCALLTYPE SetLocale(LCID lcid)
- {
- Thread *pThread = GetThread();
- if (pThread == NULL)
- return HOST_E_INVALIDOPERATION;
-
- CONTRACTL
- {
- GC_TRIGGERS;
- NOTHROW;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- //BEGIN_ENTRYPOINT_NOTHROW;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr)
- {
- pThread->SetCultureId(lcid,FALSE);
- }
- END_EXTERNAL_ENTRYPOINT;
- //END_ENTRYPOINT_NOTHROW;
- return hr;
- }
-
- virtual HRESULT STDMETHODCALLTYPE GetCurrentTaskType(ETaskType *pTaskType)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- BEGIN_ENTRYPOINT_NOTHROW;
- *pTaskType = ::GetCurrentTaskType();
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
- }
-};
-
-static CLRTaskManager s_CLRTaskManager;
-
-class CLRSyncManager : public ICLRSyncManager
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE GetMonitorOwner(SIZE_T Cookie,
- IHostTask **ppOwnerHostTask)
- {
- CONTRACTL
- {
- NOTHROW;
- MODE_PREEMPTIVE;
- GC_NOTRIGGER;
- ENTRY_POINT;;
- }
- CONTRACTL_END;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- // Cookie is the SyncBlock
- // <TODO>TODO: Lifetime of Cookie?</TODO>
- AwareLock* pAwareLock = (AwareLock*)Cookie;
- IHostTask *pTask = NULL;
- Thread *pThread = pAwareLock->GetOwningThread();
- if (pThread)
- {
- ThreadStoreLockHolder tsLock;
- pThread = pAwareLock->GetOwningThread();
- if (pThread)
- {
- // See if the lock is orphaned, and the Thread object has been deleted
- Thread *pWalk = NULL;
- while ((pWalk = ThreadStore::GetAllThreadList(pWalk, 0, 0)) != NULL)
- {
- if (pWalk == pThread)
- {
- pTask = pThread->GetHostTaskWithAddRef();
- break;
- }
- }
- }
- }
-
- *ppOwnerHostTask = pTask;
-
- END_ENTRYPOINT_NOTHROW;
-
-
- return S_OK;
- }
- virtual HRESULT STDMETHODCALLTYPE CreateRWLockOwnerIterator(SIZE_T Cookie,
- SIZE_T *pIterator) {
- Thread *pThread = GetThread();
-
- // We may open a window for GC here.
- // A host should not hijack a coop thread to do deadlock detection.
- if (pThread && pThread->PreemptiveGCDisabled())
- return HOST_E_INVALIDOPERATION;
-
- CONTRACTL
- {
- NOTHROW;
- MODE_PREEMPTIVE;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = E_FAIL;
-
-#ifdef FEATURE_RWLOCK
- BEGIN_ENTRYPOINT_NOTHROW;
- ThreadStoreLockHolder tsLock;
- // Cookie is a weak handle. We need to make sure that the object is not moving.
- CRWLock *pRWLock = *(CRWLock **) Cookie;
- *pIterator = NULL;
- if (pRWLock == NULL)
- {
- hr = S_OK;
- }
- else
- {
- hr = pRWLock->CreateOwnerIterator(pIterator);
- }
- END_ENTRYPOINT_NOTHROW;
-#endif // FEATURE_RWLOCK
-
- return hr;
- }
-
- virtual HRESULT STDMETHODCALLTYPE GetRWLockOwnerNext(SIZE_T Iterator,
- IHostTask **ppOwnerHostTask)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
-#ifdef FEATURE_RWLOCK
- BEGIN_ENTRYPOINT_NOTHROW;
- CRWLock::GetNextOwner(Iterator,ppOwnerHostTask);
- END_ENTRYPOINT_NOTHROW;
-#endif // FEATURE_RWLOCK
-
- return S_OK;
- }
-
- virtual HRESULT STDMETHODCALLTYPE DeleteRWLockOwnerIterator(SIZE_T Iterator)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
-#ifdef FEATURE_RWLOCK
- BEGIN_ENTRYPOINT_NOTHROW;
- CRWLock::DeleteOwnerIterator(Iterator);
- END_ENTRYPOINT_NOTHROW;
-#endif // FEATURE_RWLOCK
-
- return S_OK;
- }
-
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
- {
- LIMITED_METHOD_CONTRACT;
- if (riid != IID_ICLRSyncManager && riid != IID_IUnknown)
- return (E_NOINTERFACE);
- *ppvObject = this;
- return S_OK;
- }
-
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-};
-
-static CLRSyncManager s_CLRSyncManager;
-
-extern void HostIOCompletionCallback(DWORD ErrorCode,
- DWORD numBytesTransferred,
- LPOVERLAPPED lpOverlapped);
-class CCLRIoCompletionManager :public ICLRIoCompletionManager
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE OnComplete(DWORD dwErrorCode,
- DWORD NumberOfBytesTransferred,
- void* pvOverlapped)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_ENTRY_POINT;
-
- if (pvOverlapped)
- {
- BEGIN_ENTRYPOINT_NOTHROW;
- HostIOCompletionCallback (dwErrorCode, NumberOfBytesTransferred, (LPOVERLAPPED)pvOverlapped);
- END_ENTRYPOINT_NOTHROW;
- }
-
- return S_OK;
- }
-
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
- {
- STATIC_CONTRACT_SO_TOLERANT;
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- STATIC_CONTRACT_SO_TOLERANT;
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
- BEGIN_INTERFACE HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
- {
- STATIC_CONTRACT_SO_TOLERANT;
- LIMITED_METHOD_CONTRACT;
- if (riid != IID_ICLRIoCompletionManager && riid != IID_IUnknown)
- return (E_NOINTERFACE);
- *ppvObject = this;
- return S_OK;
- }
-};
-
-static CCLRIoCompletionManager s_CLRIoCompletionManager;
-#endif // FEATURE_CORECLR
-
-#ifdef _DEBUG
-extern void ValidateHostInterface();
-#endif
-
-// fusion's global copy of host assembly manager stuff
-BOOL g_bFusionHosted = FALSE;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-ICLRAssemblyReferenceList *g_pHostAsmList = NULL;
-IHostAssemblyStore *g_pHostAssemblyStore = NULL;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
-/*static*/ BOOL CorHost2::IsLoadFromBlocked() // LoadFrom, LoadFile and Load(byte[]) are blocked in certain hosting scenarios
-{
- LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- return (g_bFusionHosted && (g_pHostAsmList != NULL));
-#else // !FEATURE_INCLUDE_ALL_INTERFACES
- return FALSE; // as g_pHostAsmList is not defined for CoreCLR; hence above expression will be FALSE.
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-}
-
-static Volatile<BOOL> fOneOnly = 0;
-
-///////////////////////////////////////////////////////////////////////////////
-// ICLRRuntimeHost::SetHostControl
-///////////////////////////////////////////////////////////////////////////////
-HRESULT CorHost2::SetHostControl(IHostControl* pHostControl)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
- if (m_Version < 2)
- // CLR is hosted with v1 hosting interface. Some part of v2 hosting API are disabled.
- return HOST_E_INVALIDOPERATION;
-
- if (pHostControl == 0)
- return E_INVALIDARG;
-
- // If Runtime has been started, do not allow setting HostMemoryManager
- if (g_fEEStarted)
- return E_ACCESSDENIED;
-
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- DWORD dwSwitchCount = 0;
-
- while (FastInterlockExchange((LONG*)&fOneOnly, 1) == 1)
- {
- #ifndef FEATURE_CORECLR
- if (m_HostTaskManager != NULL)
- {
- m_HostTaskManager->SwitchToTask(0);
- }
- else
- {
- IHostTaskManager *pHostTaskManager = NULL;
- if (pHostControl->GetHostManager(IID_IHostTaskManager, (void**)&pHostTaskManager) == S_OK &&
- pHostTaskManager != NULL)
- {
- pHostTaskManager->SwitchToTask(0);
- pHostTaskManager->Release();
- }
- else
- {
- __SwitchToThread(0, ++dwSwitchCount);
- }
- }
- #else
- __SwitchToThread(0, ++dwSwitchCount);
- #endif // FEATURE_CORECLR
- }
-
-#ifndef FEATURE_CORECLR
-
-#ifdef _DEBUG
- ValidateHostInterface();
-#endif
-
-#ifdef _DEBUG
- DWORD dbg_HostManagerConfig = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_HostManagerConfig);
-#endif
-
- IHostMemoryManager *memoryManager = NULL;
- IHostTaskManager *taskManager = NULL;
- IHostThreadpoolManager *threadpoolManager = NULL;
- IHostIoCompletionManager *ioCompletionManager = NULL;
- IHostSyncManager *syncManager = NULL;
- IHostAssemblyManager *assemblyManager = NULL;
- IHostGCManager *gcManager = NULL;
- IHostSecurityManager *securityManager = NULL;
- IHostPolicyManager *policyManager = NULL;
-
- if (m_HostMemoryManager == NULL &&
-#ifdef _DEBUG
- (dbg_HostManagerConfig & CLRMEMORYHOSTED) &&
-#endif
- pHostControl->GetHostManager(IID_IHostMemoryManager,(void**)&memoryManager) == S_OK &&
- memoryManager != NULL) {
- if (m_HostMalloc == NULL)
- {
- hr = memoryManager->CreateMalloc (MALLOC_THREADSAFE, &m_HostMalloc);
- if (hr == S_OK)
- {
- memoryManager->RegisterMemoryNotificationCallback(&s_MemoryNotification);
- }
- else
- {
- memoryManager->Release();
- IfFailGo(E_UNEXPECTED);
- }
- }
- m_HostMemoryManager = memoryManager;
- g_fHostConfig |= CLRMEMORYHOSTED;
- }
-
- if (m_HostTaskManager == NULL &&
-#ifdef _DEBUG
- (dbg_HostManagerConfig & CLRTASKHOSTED) &&
-#endif
- pHostControl->GetHostManager(IID_IHostTaskManager,(void**)&taskManager) == S_OK &&
- taskManager != NULL) {
-#ifdef _TARGET_ARM_ // @ARMTODO: re-enable once we support hosted p/invokes.
- IfFailGo(E_NOTIMPL);
-#endif
- m_HostTaskManager = taskManager;
- m_HostTaskManager->SetCLRTaskManager(&s_CLRTaskManager);
- g_fHostConfig |= CLRTASKHOSTED;
- }
-
- if (m_HostThreadpoolManager == NULL &&
-#ifdef _DEBUG
- (dbg_HostManagerConfig & CLRTHREADPOOLHOSTED) &&
-#endif
- pHostControl->GetHostManager(IID_IHostThreadpoolManager,(void**)&threadpoolManager) == S_OK &&
- threadpoolManager != NULL) {
- m_HostThreadpoolManager = threadpoolManager;
- g_fHostConfig |= CLRTHREADPOOLHOSTED;
+ GC_NOTRIGGER;
+ ENTRY_POINT;
}
+ CONTRACTL_END;
- if (m_HostIoCompletionManager == NULL &&
-#ifdef _DEBUG
- (dbg_HostManagerConfig & CLRIOCOMPLETIONHOSTED) &&
-#endif
- pHostControl->GetHostManager(IID_IHostIoCompletionManager,(void**)&ioCompletionManager) == S_OK &&
- ioCompletionManager != NULL) {
- DWORD hostSize;
- hr = ioCompletionManager->GetHostOverlappedSize(&hostSize);
- if (FAILED(hr))
- {
- ioCompletionManager->Release();
- IfFailGo(E_UNEXPECTED);
- }
- m_HostOverlappedExtensionSize = (int)hostSize;
- m_HostIoCompletionManager = ioCompletionManager;
- m_HostIoCompletionManager->SetCLRIoCompletionManager(&s_CLRIoCompletionManager);
- g_fHostConfig |= CLRIOCOMPLETIONHOSTED;
- }
+ BEGIN_ENTRYPOINT_NOTHROW;
- if (m_HostSyncManager == NULL &&
-#ifdef _DEBUG
- (dbg_HostManagerConfig & CLRSYNCHOSTED) &&
-#endif
- pHostControl->GetHostManager(IID_IHostSyncManager,(void**)&syncManager) == S_OK &&
- syncManager != NULL) {
- m_HostSyncManager = syncManager;
- m_HostSyncManager->SetCLRSyncManager(&s_CLRSyncManager);
- g_fHostConfig |= CLRSYNCHOSTED;
- }
+ Thread* pThread = GetThread();
+ if (pThread == NULL)
+ *pCount = 0;
+ else
+ *pCount = pThread->m_dwLockCount;
- if (m_HostAssemblyManager == NULL &&
-#ifdef _DEBUG
- (dbg_HostManagerConfig & CLRASSEMBLYHOSTED) &&
-#endif
- pHostControl->GetHostManager(IID_IHostAssemblyManager,(void**)&assemblyManager) == S_OK &&
- assemblyManager != NULL) {
+ END_ENTRYPOINT_NOTHROW;
- assemblyManager->GetAssemblyStore(&g_pHostAssemblyStore);
+ return S_OK;
+}
- hr = assemblyManager->GetNonHostStoreAssemblies(&g_pHostAsmList);
- if (FAILED(hr))
- {
- assemblyManager->Release();
- IfFailGo(hr);
- }
+//*****************************************************************************
+// ICorConfiguration
+//*****************************************************************************
- if (g_pHostAssemblyStore || g_pHostAsmList)
- g_bFusionHosted = TRUE;
- m_HostAssemblyManager = assemblyManager;
- g_fHostConfig |= CLRASSEMBLYHOSTED;
- }
+//*****************************************************************************
+// IUnknown
+//*****************************************************************************
- if (m_HostGCManager == NULL &&
-#ifdef _DEBUG
- (dbg_HostManagerConfig & CLRGCHOSTED) &&
-#endif
- pHostControl->GetHostManager(IID_IHostGCManager,
- (void**)&gcManager) == S_OK &&
- gcManager != NULL) {
- m_HostGCManager = gcManager;
- g_fHostConfig |= CLRGCHOSTED;
+ULONG CorRuntimeHostBase::AddRef()
+{
+ CONTRACTL
+ {
+ WRAPPER(THROWS);
+ WRAPPER(GC_TRIGGERS);
+ SO_TOLERANT;
}
+ CONTRACTL_END;
+ return InterlockedIncrement(&m_cRef);
+}
- if (m_HostSecurityManager == NULL &&
-#ifdef _DEBUG
- (dbg_HostManagerConfig & CLRSECURITYHOSTED) &&
-#endif
- pHostControl->GetHostManager(IID_IHostSecurityManager,
- (void**)&securityManager) == S_OK &&
- securityManager != NULL) {
- g_fHostConfig |= CLRSECURITYHOSTED;
- m_HostSecurityManager = securityManager;
-#ifdef FEATURE_CAS_POLICY
- HostExecutionContextManager::InitializeRestrictedContext();
-#endif // #ifdef FEATURE_CAS_POLICY
- }
- if (m_HostPolicyManager == NULL &&
- pHostControl->GetHostManager(IID_IHostPolicyManager,
- (void**)&policyManager) == S_OK &&
- policyManager != NULL) {
- m_HostPolicyManager = policyManager;
- }
-#endif //!FEATURE_CORECLR
+ULONG CorHost2::Release()
+{
+ LIMITED_METHOD_CONTRACT;
- if (m_HostControl == NULL)
- {
- m_HostControl = pHostControl;
- m_HostControl->AddRef();
+ ULONG cRef = InterlockedDecrement(&m_cRef);
+ if (!cRef) {
+#ifdef FEATURE_INCLUDE_ALL_INTERFACES
+ // CorHost2 is allocated before host memory interface is set up.
+ if (GetHostMemoryManager() == NULL)
+#endif // FEATURE_INCLUDE_ALL_INTERFACES
+ delete this;
}
- goto ErrExit;
-
-ErrExit:
- fOneOnly = 0;
+ return (cRef);
+}
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-class CCLRPolicyManager: public ICLRPolicyManager
+HRESULT CorHost2::QueryInterface(REFIID riid, void **ppUnk)
{
-public:
- virtual HRESULT STDMETHODCALLTYPE SetDefaultAction(EClrOperation operation,
- EPolicyAction action)
- {
- LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- STATIC_CONTRACT_ENTRY_POINT;
- HRESULT hr;
- BEGIN_ENTRYPOINT_NOTHROW;
- hr = GetEEPolicy()->SetDefaultAction(operation, action);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-#else // FEATURE_CORECLR
- return E_NOTIMPL;
-#endif // !FEATURE_CORECLR
- }
+ if (!ppUnk)
+ return E_POINTER;
- virtual HRESULT STDMETHODCALLTYPE SetTimeout(EClrOperation operation,
- DWORD dwMilliseconds)
+ CONTRACTL
{
- LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- STATIC_CONTRACT_ENTRY_POINT;
- HRESULT hr;
- BEGIN_ENTRYPOINT_NOTHROW;
- hr = GetEEPolicy()->SetTimeout(operation,dwMilliseconds);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-#else // FEATURE_CORECLR
- return E_NOTIMPL;
-#endif // !FEATURE_CORECLR
+ NOTHROW;
+ GC_NOTRIGGER;
+ SO_TOLERANT; // no global state updates that need guarding.
}
+ CONTRACTL_END;
- virtual HRESULT STDMETHODCALLTYPE SetActionOnTimeout(EClrOperation operation,
- EPolicyAction action)
+ if (ppUnk == NULL)
{
- LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- STATIC_CONTRACT_ENTRY_POINT;
- HRESULT hr;
- BEGIN_ENTRYPOINT_NOTHROW;
- hr = GetEEPolicy()->SetActionOnTimeout(operation,action);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-#else // FEATURE_CORECLR
- return E_NOTIMPL;
-#endif // !FEATURE_CORECLR
+ return E_POINTER;
}
- virtual HRESULT STDMETHODCALLTYPE SetTimeoutAndAction(EClrOperation operation, DWORD dwMilliseconds,
- EPolicyAction action)
- {
- LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- STATIC_CONTRACT_SO_TOLERANT;
- HRESULT hr;
- BEGIN_ENTRYPOINT_NOTHROW;
- hr = GetEEPolicy()->SetTimeoutAndAction(operation,dwMilliseconds,action);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-#else // FEATURE_CORECLR
- return E_NOTIMPL;
-#endif // !FEATURE_CORECLR
- }
+ *ppUnk = 0;
- virtual HRESULT STDMETHODCALLTYPE SetActionOnFailure(EClrFailure failure,
- EPolicyAction action)
+ // Deliberately do NOT hand out ICorConfiguration. They must explicitly call
+ // GetConfiguration to obtain that interface.
+ if (riid == IID_IUnknown)
+ *ppUnk = static_cast<IUnknown *>(static_cast<ICLRRuntimeHost *>(this));
+ else if (riid == IID_ICLRRuntimeHost2)
{
- // This is enabled for CoreCLR since a host can use this to
- // specify action for handling AV.
- STATIC_CONTRACT_ENTRY_POINT;
- LIMITED_METHOD_CONTRACT;
- HRESULT hr;
-#ifdef FEATURE_CORECLR
- // For CoreCLR, this method just supports FAIL_AccessViolation as a valid
- // failure input arg. The validation of the specified action for the failure
- // will be done in EEPolicy::IsValidActionForFailure.
- if (failure != FAIL_AccessViolation)
- {
- return E_INVALIDARG;
- }
-#endif // FEATURE_CORECLR
- BEGIN_ENTRYPOINT_NOTHROW;
- hr = GetEEPolicy()->SetActionOnFailure(failure,action);
- END_ENTRYPOINT_NOTHROW;
- return hr;
- }
+ ULONG version = 2;
+ if (m_Version == 0)
+ FastInterlockCompareExchange((LONG*)&m_Version, version, 0);
- virtual HRESULT STDMETHODCALLTYPE SetUnhandledExceptionPolicy(EClrUnhandledException policy)
- {
- LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- STATIC_CONTRACT_ENTRY_POINT;
- HRESULT hr;
- BEGIN_ENTRYPOINT_NOTHROW;
- hr = GetEEPolicy()->SetUnhandledExceptionPolicy(policy);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-#else // FEATURE_CORECLR
- return E_NOTIMPL;
-#endif // !FEATURE_CORECLR
+ *ppUnk = static_cast<ICLRRuntimeHost2 *>(this);
}
-
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
+ else if (riid == IID_ICLRExecutionManager)
{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return 1;
- }
+ ULONG version = 2;
+ if (m_Version == 0)
+ FastInterlockCompareExchange((LONG*)&m_Version, version, 0);
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return 1;
+ *ppUnk = static_cast<ICLRExecutionManager *>(this);
}
-
- BEGIN_INTERFACE HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,
- void **ppvObject)
+#ifndef FEATURE_PAL
+ else if (riid == IID_IPrivateManagedExceptionReporting)
{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- if (riid != IID_ICLRPolicyManager && riid != IID_IUnknown)
- return (E_NOINTERFACE);
-
- // Ensure that the out going pointer is not null
- if (ppvObject == NULL)
- return E_POINTER;
-
- *ppvObject = this;
- return S_OK;
+ *ppUnk = static_cast<IPrivateManagedExceptionReporting *>(this);
}
-};
+#endif // !FEATURE_PAL
+ else
+ return (E_NOINTERFACE);
+ AddRef();
+ return (S_OK);
+}
-static CCLRPolicyManager s_PolicyManager;
-#ifndef FEATURE_CORECLR // not supported
-class CCLROnEventManager: public ICLROnEventManager
+#ifndef FEATURE_PAL
+HRESULT CorHost2::GetBucketParametersForCurrentException(BucketParameters *pParams)
{
-public:
- virtual HRESULT STDMETHODCALLTYPE RegisterActionOnEvent(EClrEvent event,
- IActionOnCLREvent *pAction)
+ CONTRACTL
{
- CONTRACTL
- {
- GC_TRIGGERS;
- NOTHROW;
- ENTRY_POINT;
-
- // This function is always called from outside the Runtime. So, we assert that we either don't have a
- // managed thread, or if we do, that we're in preemptive GC mode.
- PRECONDITION((GetThread() == NULL) || !GetThread()->PreemptiveGCDisabled());
- }
- CONTRACTL_END;
-
- if (event >= MaxClrEvent || pAction == NULL || event < (EClrEvent)0)
- return E_INVALIDARG;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- // Note: its only safe to use a straight ReleaseHolder from within the VM directory when we know we're
- // called from outside the Runtime. We assert that above, just to be sure.
- ReleaseHolder<IActionOnCLREvent> actionHolder(pAction);
- pAction->AddRef();
-
- CrstHolderWithState ch(m_pLock);
-
- DWORD dwSwitchCount = 0;
- while (m_ProcessEvent != 0)
- {
- ch.Release();
- __SwitchToThread(0, ++dwSwitchCount);
- ch.Acquire();
- }
-
- if (m_pAction[event] == NULL)
- {
- m_pAction[event] = new (nothrow)ActionNode;
- if (m_pAction[event] == NULL)
- hr = E_OUTOFMEMORY;
- }
-
- if (SUCCEEDED(hr))
- {
- ActionNode *walk = m_pAction[event];
- while (TRUE)
- {
- int n = 0;
- for ( ; n < ActionNode::ActionArraySize; n ++)
- {
- if (walk->pAction[n] == NULL)
- {
- walk->pAction[n] = pAction;
- actionHolder.SuppressRelease();
- hr = S_OK;
- break;
- }
- }
- if (n < ActionNode::ActionArraySize)
- {
- break;
- }
- if (walk->pNext == NULL)
- {
- walk->pNext = new (nothrow) ActionNode;
- if (walk->pNext == NULL)
- {
- hr = E_OUTOFMEMORY;
- break;
- }
- }
- walk = walk->pNext;
- }
- }
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
+ NOTHROW;
+ GC_NOTRIGGER;
+ SO_TOLERANT;
}
+ CONTRACTL_END;
- virtual HRESULT STDMETHODCALLTYPE UnregisterActionOnEvent(EClrEvent event,
- IActionOnCLREvent *pAction)
- {
- CONTRACTL
- {
- GC_NOTRIGGER;
- NOTHROW;
- ENTRY_POINT;
- }
- CONTRACTL_END;
+ HRESULT hr = S_OK;
+ BEGIN_ENTRYPOINT_NOTHROW;
- if (event == Event_StackOverflow)
- {
- // We don't want to take a lock when we process StackOverflow event, because we may
- // not have enough stack to do it.
- // So we do not release our cache of the callback in order to avoid race.
- return HOST_E_INVALIDOPERATION;
- }
+ // To avoid confusion, clear the buckets.
+ memset(pParams, 0, sizeof(BucketParameters));
- HRESULT hr = S_OK;
+ // Defer to Watson helper.
+ hr = ::GetBucketParametersForCurrentException(pParams);
- ActionNode *walk = NULL;
- ActionNode *prev = NULL;
+ END_ENTRYPOINT_NOTHROW;
+ return hr;
+}
+#endif // !FEATURE_PAL
- BEGIN_ENTRYPOINT_NOTHROW;
+HRESULT CorHost2::CreateObject(REFIID riid, void **ppUnk)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ SO_TOLERANT;
+ }
+ CONTRACTL_END;
- CrstHolderWithState ch(m_pLock);
+ HRESULT hr = S_OK;
- DWORD dwSwitchCount = 0;
- while (m_ProcessEvent != 0)
- {
- ch.Release();
- __SwitchToThread(0, ++dwSwitchCount);
- ch.Acquire();
- }
+ BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW; );
+ CorHost2 *pCorHost = new (nothrow) CorHost2();
+ if (!pCorHost)
+ {
+ hr = E_OUTOFMEMORY;
+ }
+ else
+ {
+ hr = pCorHost->QueryInterface(riid, ppUnk);
+ if (FAILED(hr))
+ delete pCorHost;
+ }
+ END_SO_INTOLERANT_CODE;
+ return (hr);
+}
- if (m_pAction[event] == NULL)
- IfFailGo(HOST_E_INVALIDOPERATION);
- walk = m_pAction[event];
- while (walk)
- {
- BOOL fInUse = FALSE;
- for (int n = 0; n < ActionNode::ActionArraySize; n ++)
- {
- if (prev && !fInUse && walk->pAction[n])
- fInUse = TRUE;
- if (walk->pAction[n] == pAction)
- {
- walk->pAction[n] = NULL;
- ch.Release();
- pAction->Release();
- hr = S_OK;
- goto ErrExit;
- }
- }
- if (prev && !fInUse)
- {
- prev->pNext = walk->pNext;
- delete walk;
- walk = prev;
- }
- prev = walk;
- walk = walk->pNext;
- }
- hr = HOST_E_INVALIDOPERATION;
-ErrExit:
- END_ENTRYPOINT_NOTHROW;
+//-----------------------------------------------------------------------------
+// MapFile - Maps a file into the runtime in a non-standard way
+//-----------------------------------------------------------------------------
- return hr;
+static PEImage *MapFileHelper(HANDLE hFile)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
}
+ CONTRACTL_END;
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
+ GCX_PREEMP();
+
+ HandleHolder hFileMap(WszCreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL));
+ if (hFileMap == NULL)
+ ThrowLastError();
+
+ CLRMapViewHolder base(CLRMapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0));
+ if (base == NULL)
+ ThrowLastError();
+
+ DWORD dwSize = SafeGetFileSize(hFile, NULL);
+ if (dwSize == 0xffffffff && GetLastError() != NOERROR)
{
- STATIC_CONTRACT_SO_TOLERANT;
- LIMITED_METHOD_CONTRACT;
- return 1;
+ ThrowLastError();
}
+ PEImageHolder pImage(PEImage::LoadFlat(base, dwSize));
+ return pImage.Extract();
+}
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppUnk)
+HRESULT CorRuntimeHostBase::MapFile(HANDLE hFile, HMODULE* phHandle)
+{
+ CONTRACTL
{
- STATIC_CONTRACT_SO_TOLERANT;
- LIMITED_METHOD_CONTRACT;
- if (riid != IID_ICLROnEventManager && riid != IID_IUnknown)
- return (E_NOINTERFACE);
- *ppUnk = this;
- return S_OK;
+ NOTHROW;
+ GC_TRIGGERS;
+ MODE_PREEMPTIVE;
+ ENTRY_POINT;
}
+ CONTRACTL_END;
- virtual ULONG STDMETHODCALLTYPE Release(void)
+ HRESULT hr;
+ BEGIN_ENTRYPOINT_NOTHROW;
+
+ BEGIN_EXTERNAL_ENTRYPOINT(&hr)
{
- STATIC_CONTRACT_SO_TOLERANT;
- LIMITED_METHOD_CONTRACT;
- return 1;
+ *phHandle = (HMODULE) (MapFileHelper(hFile)->GetLoadedLayout()->GetBase());
}
+ END_EXTERNAL_ENTRYPOINT;
+ END_ENTRYPOINT_NOTHROW;
- // This function is to work around an issue in scan.exe.
- // scan.exe is not smart to handle that if (){} else {}.
- void ProcessSOEvent(void *data)
- {
- STATIC_CONTRACT_SO_TOLERANT;
- WRAPPER_NO_CONTRACT;
- if (m_pLock == NULL)
- return;
+ return hr;
+}
- ActionNode *walk = m_pAction[Event_StackOverflow];
+///////////////////////////////////////////////////////////////////////////////
+// IDebuggerInfo::IsDebuggerAttached
- while (walk)
- {
- for (int n = 0; n < ActionNode::ActionArraySize; n ++)
- {
- if (walk->pAction[n])
- {
- walk->pAction[n]->OnEvent(Event_StackOverflow,data);
- }
- }
- walk = walk->pNext;
- }
- }
+LONG CorHost2::m_RefCount = 0;
- void ProcessEvent(EClrEvent event, void *data)
- {
- WRAPPER_NO_CONTRACT;
+IHostControl *CorHost2::m_HostControl = NULL;
- if (m_pLock == NULL)
- {
- return;
- }
+LPCWSTR CorHost2::s_wszAppDomainManagerAsm = NULL;
+LPCWSTR CorHost2::s_wszAppDomainManagerType = NULL;
+EInitializeNewDomainFlags CorHost2::s_dwDomainManagerInitFlags = eInitializeNewDomainFlags_None;
- _ASSERTE (event != Event_StackOverflow);
- {
- CrstHolder ch(m_pLock);
+#ifdef _DEBUG
+extern void ValidateHostInterface();
+#endif
- if (event == Event_ClrDisabled)
- {
- if (m_CLRDisabled)
- {
- return;
- }
- m_CLRDisabled = TRUE;
- }
- m_ProcessEvent ++;
+// fusion's global copy of host assembly manager stuff
+BOOL g_bFusionHosted = FALSE;
+#ifdef FEATURE_INCLUDE_ALL_INTERFACES
+ICLRAssemblyReferenceList *g_pHostAsmList = NULL;
+IHostAssemblyStore *g_pHostAssemblyStore = NULL;
+#endif // FEATURE_INCLUDE_ALL_INTERFACES
- // Release the lock around the call into the host. Is this correct?
- // It seems that we need to hold the lock except for the actual callback itself.
- }
+/*static*/ BOOL CorHost2::IsLoadFromBlocked() // LoadFrom, LoadFile and Load(byte[]) are blocked in certain hosting scenarios
+{
+ LIMITED_METHOD_CONTRACT;
+#ifdef FEATURE_INCLUDE_ALL_INTERFACES
+ return (g_bFusionHosted && (g_pHostAsmList != NULL));
+#else // !FEATURE_INCLUDE_ALL_INTERFACES
+ return FALSE; // as g_pHostAsmList is not defined for CoreCLR; hence above expression will be FALSE.
+#endif // FEATURE_INCLUDE_ALL_INTERFACES
+}
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- {
- ActionNode *walk = m_pAction[event];
- while (walk)
- {
- for (int n = 0; n < ActionNode::ActionArraySize; n ++)
- {
- if (walk->pAction[n])
- {
- walk->pAction[n]->OnEvent(event,data);
- }
- }
- walk = walk->pNext;
- }
- }
- END_SO_TOLERANT_CODE_CALLING_HOST;
+static Volatile<BOOL> fOneOnly = 0;
- {
- CrstHolder ch(m_pLock);
- m_ProcessEvent --;
- }
+///////////////////////////////////////////////////////////////////////////////
+// ICLRRuntimeHost::SetHostControl
+///////////////////////////////////////////////////////////////////////////////
+HRESULT CorHost2::SetHostControl(IHostControl* pHostControl)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ ENTRY_POINT;
}
+ CONTRACTL_END;
+ if (m_Version < 2)
+ // CLR is hosted with v1 hosting interface. Some part of v2 hosting API are disabled.
+ return HOST_E_INVALIDOPERATION;
- BOOL IsActionRegisteredForEvent(EClrEvent event)
- {
- WRAPPER_NO_CONTRACT;
+ if (pHostControl == 0)
+ return E_INVALIDARG;
- // Check to see if the event manager has been set up.
- if (m_pLock == NULL)
- return FALSE;
+ // If Runtime has been started, do not allow setting HostMemoryManager
+ if (g_fEEStarted)
+ return E_ACCESSDENIED;
- CrstHolder ch(m_pLock);
+ HRESULT hr = S_OK;
- ActionNode *walk = m_pAction[event];
- while (walk)
- {
- for (int n = 0; n < ActionNode::ActionArraySize; n ++)
- {
- if (walk->pAction[n] != NULL)
- {
- // We found an action registered for this event.
- return TRUE;
- }
- }
- walk = walk->pNext;
- }
+ BEGIN_ENTRYPOINT_NOTHROW;
+
+ DWORD dwSwitchCount = 0;
- // There weren't any actions registered.
- return FALSE;
+ while (FastInterlockExchange((LONG*)&fOneOnly, 1) == 1)
+ {
+ __SwitchToThread(0, ++dwSwitchCount);
}
+
- HRESULT Init()
+ if (m_HostControl == NULL)
{
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_NOTRIGGER;
- STATIC_CONTRACT_MODE_ANY;
- STATIC_CONTRACT_SO_TOLERANT;
+ m_HostControl = pHostControl;
+ m_HostControl->AddRef();
+ }
- HRESULT hr = S_OK;
- if (m_pLock == NULL)
- {
- EX_TRY
- {
- BEGIN_SO_INTOLERANT_CODE(GetThread());
- {
- InitHelper();
- }
- END_SO_INTOLERANT_CODE;
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
- }
+ goto ErrExit;
- return hr;
+ErrExit:
+ fOneOnly = 0;
+
+ END_ENTRYPOINT_NOTHROW;
+
+ return hr;
+}
+
+class CCLRPolicyManager: public ICLRPolicyManager
+{
+public:
+ virtual HRESULT STDMETHODCALLTYPE SetDefaultAction(EClrOperation operation,
+ EPolicyAction action)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return E_NOTIMPL;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE SetTimeout(EClrOperation operation,
+ DWORD dwMilliseconds)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return E_NOTIMPL;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE SetActionOnTimeout(EClrOperation operation,
+ EPolicyAction action)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return E_NOTIMPL;
}
-#if 0
- // We do not need this one. We have one instance of this class
- // and it is static.
- CCLROnEventManager()
+ virtual HRESULT STDMETHODCALLTYPE SetTimeoutAndAction(EClrOperation operation, DWORD dwMilliseconds,
+ EPolicyAction action)
{
LIMITED_METHOD_CONTRACT;
- for (int n = 0; n < MaxClrEvent; n ++)
- m_pAction[n] = NULL;
+ return E_NOTIMPL;
}
-#endif
-private:
- struct ActionNode
+ virtual HRESULT STDMETHODCALLTYPE SetActionOnFailure(EClrFailure failure,
+ EPolicyAction action)
{
- static const int ActionArraySize = 8;
-
- IActionOnCLREvent *pAction[ActionArraySize];
- ActionNode *pNext;
-
- ActionNode ()
- : pNext(NULL)
+ // This is enabled for CoreCLR since a host can use this to
+ // specify action for handling AV.
+ STATIC_CONTRACT_ENTRY_POINT;
+ LIMITED_METHOD_CONTRACT;
+ HRESULT hr;
+ // For CoreCLR, this method just supports FAIL_AccessViolation as a valid
+ // failure input arg. The validation of the specified action for the failure
+ // will be done in EEPolicy::IsValidActionForFailure.
+ if (failure != FAIL_AccessViolation)
{
- LIMITED_METHOD_CONTRACT;
-
- for (int n = 0; n < ActionArraySize; n ++)
- pAction[n] = 0;
+ return E_INVALIDARG;
}
- };
- ActionNode *m_pAction[MaxClrEvent];
+ BEGIN_ENTRYPOINT_NOTHROW;
+ hr = GetEEPolicy()->SetActionOnFailure(failure,action);
+ END_ENTRYPOINT_NOTHROW;
+ return hr;
+ }
- Crst* m_pLock;
+ virtual HRESULT STDMETHODCALLTYPE SetUnhandledExceptionPolicy(EClrUnhandledException policy)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return E_NOTIMPL;
+ }
- BOOL m_CLRDisabled;
+ virtual ULONG STDMETHODCALLTYPE AddRef(void)
+ {
+ LIMITED_METHOD_CONTRACT;
+ STATIC_CONTRACT_SO_TOLERANT;
+ return 1;
+ }
- // We can not call out into host while holding the lock. At the same time
- // we need to make our data consistent. Therefore, m_ProcessEvent is a marker
- // to forbid touching the data structure from Register and UnRegister.
- DWORD m_ProcessEvent;
+ virtual ULONG STDMETHODCALLTYPE Release(void)
+ {
+ LIMITED_METHOD_CONTRACT;
+ STATIC_CONTRACT_SO_TOLERANT;
+ return 1;
+ }
- void InitHelper()
+ BEGIN_INTERFACE HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,
+ void **ppvObject)
{
- CONTRACTL
- {
- GC_NOTRIGGER;
- THROWS;
- MODE_ANY;
- }
- CONTRACTL_END;
+ LIMITED_METHOD_CONTRACT;
+ STATIC_CONTRACT_SO_TOLERANT;
+ if (riid != IID_ICLRPolicyManager && riid != IID_IUnknown)
+ return (E_NOINTERFACE);
- m_ProcessEvent = 0;
+ // Ensure that the out going pointer is not null
+ if (ppvObject == NULL)
+ return E_POINTER;
- Crst* tmp = new Crst(CrstOnEventManager, CrstFlags(CRST_DEFAULT | CRST_DEBUGGER_THREAD));
- if (FastInterlockCompareExchangePointer(&m_pLock, tmp, NULL) != NULL)
- delete tmp;
+ *ppvObject = this;
+ return S_OK;
}
};
-static CCLROnEventManager s_OnEventManager;
-#endif // FEATURE_CORECLR
+static CCLRPolicyManager s_PolicyManager;
+
void ProcessEventForHost(EClrEvent event, void *data)
{
-#ifndef FEATURE_CORECLR
- WRAPPER_NO_CONTRACT;
-
- _ASSERTE (event != Event_StackOverflow);
-
- GCX_PREEMP();
-
- s_OnEventManager.ProcessEvent(event,data);
-#endif // FEATURE_CORECLR
}
// We do not call ProcessEventForHost for stack overflow, since we have limit stack
// and we should avoid calling GCX_PREEMPT
void ProcessSOEventForHost(EXCEPTION_POINTERS *pExceptionInfo, BOOL fInSoTolerant)
{
-#ifndef FEATURE_CORECLR
- WRAPPER_NO_CONTRACT;
-
- StackOverflowInfo soInfo;
- if (fInSoTolerant)
- {
- soInfo.soType = SO_Managed;
- }
- else if (pExceptionInfo == NULL || IsIPInModule(g_pMSCorEE, GetIP(pExceptionInfo->ContextRecord)))
- {
- soInfo.soType = SO_ClrEngine;
- }
- else
- {
- soInfo.soType = SO_Other;
- }
-
- soInfo.pExceptionInfo = pExceptionInfo;
- s_OnEventManager.ProcessSOEvent(&soInfo);
-#endif // FEATURE_CORECLR
}
BOOL IsHostRegisteredForEvent(EClrEvent event)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CORECLR
return FALSE;
-#else // FEATURE_CORECLR
- return s_OnEventManager.IsActionRegisteredForEvent(event);
-#endif // FEATURE_CORECLR
}
inline size_t SizeInKBytes(size_t cbSize)
}
}
-#if !defined(FEATURE_CORECLR) || defined(FEATURE_WINDOWSPHONE)
+#if defined(FEATURE_WINDOWSPHONE)
class CCLRGCManager: public ICLRGCManager2
{
public:
static CCLRAppDomainResourceMonitor s_Arm;
#endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING
-#ifdef FEATURE_APTCA
-class CLRDomainManager : public ICLRDomainManager
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE SetAppDomainManagerType(__in LPCWSTR wszAppDomainManagerAssembly,
- __in LPCWSTR wszAppDomainManagerType,
- EInitializeNewDomainFlags dwInitializeDomainFlags)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- hr = CorHost2::SetAppDomainManagerType(wszAppDomainManagerAssembly,
- wszAppDomainManagerType,
- dwInitializeDomainFlags);
- END_ENTRYPOINT_NOTHROW;
- return hr;
- }
-
- virtual HRESULT STDMETHODCALLTYPE SetPropertiesForDefaultAppDomain(DWORD nProperties,
- __in_ecount(nProperties) LPCWSTR *pwszPropertyNames,
- __in_ecount(nProperties) LPCWSTR *pwszPropertyValues)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- hr = CorHost2::SetPropertiesForDefaultAppDomain(nProperties, pwszPropertyNames, pwszPropertyValues);
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
- }
-
- virtual ULONG STDMETHODCALLTYPE AddRef()
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- virtual ULONG STDMETHODCALLTYPE Release()
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(__in REFIID riid, __out LPVOID *ppvObject)
- {
- LIMITED_METHOD_CONTRACT;
-
- if (ppvObject == NULL)
- return E_POINTER;
-
- *ppvObject = NULL;
-
- if (riid == IID_ICLRDomainManager)
- {
- *ppvObject = this;
- }
- else if (riid == IID_IUnknown)
- {
- *ppvObject = static_cast<IUnknown *>(this);
- }
-
- if (*ppvObject == NULL)
- return E_NOINTERFACE;
-
- AddRef();
- return S_OK;
- }
-};
-
-static CLRDomainManager s_CLRDomainManager;
-#endif // FEATURE_APTCA
BOOL g_CLRPolicyRequested = FALSE;
if (ppObject == NULL)
return E_INVALIDARG;
-#ifndef FEATURE_CORECLR
- // ErrorReportingManager is allowed, even if runtime is started, so
- // make this check first.
- // Host must call release on CLRErrorReportingManager after this call
- if (riid == IID_ICLRErrorReportingManager)
- {
- *ppObject = &g_CLRErrorReportingManager;
- return S_OK;
- }
- else
-#elif defined(FEATURE_WINDOWSPHONE)
+#if defined(FEATURE_WINDOWSPHONE)
if (riid == IID_ICLRErrorReportingManager2)
{
*ppObject = &g_CLRErrorReportingManager;
// If runtime has been started, do not allow user to obtain CLR managers.
return HOST_E_INVALIDOPERATION;
}
-#ifndef FEATURE_CORECLR
- else if (riid == IID_ICLRTaskManager) {
- *ppObject = &s_CLRTaskManager;
- return S_OK;
- }
-#endif // !FEATURE_CORECLR
// CoreCLR supports ICLRPolicyManager since it allows the host
// to specify the policy for AccessViolation.
FastInterlockExchange((LONG*)&g_CLRPolicyRequested, TRUE);
return S_OK;
}
-#ifndef FEATURE_CORECLR
- else if (riid == IID_ICLRHostProtectionManager) {
- *ppObject = GetHostProtectionManager();
- return S_OK;
- }
-
- // Host must call release on CLRDebugManager after this call
- else if (riid == IID_ICLRDebugManager)
- {
- *ppObject = &s_CLRDebugManager;
- return S_OK;
- }
-
- else if (riid == IID_ICLROnEventManager)
- {
- HRESULT hr = s_OnEventManager.Init();
- if (FAILED(hr))
- return hr;
- *ppObject = &s_OnEventManager;
- return S_OK;
- }
-#endif // !FEATURE_CORECLR
-#if !defined(FEATURE_CORECLR) || defined(FEATURE_WINDOWSPHONE)
+#if defined(FEATURE_WINDOWSPHONE)
else if ((riid == IID_ICLRGCManager) || (riid == IID_ICLRGCManager2))
{
*ppObject = &s_GCManager;
return S_OK;
}
#endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING
-#ifdef FEATURE_APTCA
- else if (riid == IID_ICLRDomainManager)
- {
- *ppObject = &s_CLRDomainManager;
- return S_OK;
- }
-#endif // FEATURE_APTCA
else
return (E_NOINTERFACE);
}
LPCWSTR pwzAppDomainManagerAssembly,
LPCWSTR pwzAppDomainManagerType)
{
-#ifndef FEATURE_CORECLR
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT; // no global state updates
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- hr = CorHost2::SetAppDomainManagerType(pwzAppDomainManagerAssembly,
- pwzAppDomainManagerType,
- eInitializeNewDomainFlags_None);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-#else // FEATURE_CORECLR
// CoreCLR does not support this method
return E_NOTIMPL;
-#endif // !FEATURE_CORECLR
}
virtual ULONG STDMETHODCALLTYPE AddRef(void)
// After CLR starts, we give out s_CorCLRControlLimited which allows limited access to managers.
static CCorCLRControl s_CorCLRControl;
-#ifndef FEATURE_CORECLR
-static CCorCLRControl s_CorCLRControlLimited;
-#endif // FEATURE_CORECLR
///////////////////////////////////////////////////////////////////////////////
// ICLRRuntimeHost::GetCLRControl
}
else
{
-#ifndef FEATURE_CORECLR
- // Even CLR is hosted by v1 hosting interface, we still allow part of CLRControl, like IID_ICLRErrorReportingManager.
- s_CorCLRControlLimited.SetAccess(FALSE);
- *pCLRControl = &s_CorCLRControlLimited;
-#else // FEATURE_CORECLR
// If :
// 1) request comes for interface other than ICLRControl*, OR
// 2) runtime has already started, OR
{
hr = E_NOTIMPL;
}
-#endif // !FEATURE_CORECLR
}
END_ENTRYPOINT_NOTHROW;
return hr;
}
-#ifndef FEATURE_CORECLR
-
-// static
-HRESULT CorHost2::SetPropertiesForDefaultAppDomain(DWORD nProperties,
- __in_ecount(nProperties) LPCWSTR *pwszPropertyNames,
- __in_ecount(nProperties) LPCWSTR *pwszPropertyValues)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- // Default domain properties can only be set before the CLR has started
- if (g_fEEStarted || HasStarted())
- {
- return HOST_E_INVALIDOPERATION;
- }
-
- // If the host is specifying properties, they should be there
- if (nProperties > 0 && (pwszPropertyNames == NULL || pwszPropertyValues == NULL))
- {
- return E_POINTER;
- }
-
- // v4 - since this property is being added late in the cycle to address a specific scenario, we
- // reject any attempt to set anything but a single well known property name. This restriction
- // can be removed in the future.
- for (DWORD iProperty = 0; iProperty < nProperties; ++iProperty)
- {
- if (pwszPropertyNames[iProperty] == NULL)
- {
- return E_POINTER;
- }
- if (pwszPropertyValues[iProperty] == NULL)
- {
- return E_POINTER;
- }
- if (wcscmp(PARTIAL_TRUST_VISIBLE_ASSEMBLIES_PROPERTY, pwszPropertyNames[iProperty]) != 0)
- {
- return HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY);
- }
- }
-
- HRESULT hr = S_OK;
-
- EX_TRY
- {
- for (DWORD iProperty = 0; iProperty < nProperties; ++iProperty)
- {
- SString propertyName(pwszPropertyNames[iProperty]);
- s_defaultDomainPropertyNames.Append(propertyName);
-
- SString propertyValue(pwszPropertyValues[iProperty]);
- s_defaultDomainPropertyValues.Append(propertyValue);
- }
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-
-// static
-HRESULT CorHost2::SetAppDomainManagerType(LPCWSTR wszAppDomainManagerAssembly,
- LPCWSTR wszAppDomainManagerType,
- EInitializeNewDomainFlags dwInitializeDomainFlags)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- // The AppDomainManger can only be set by the host before the CLR has started
- if (g_fEEStarted || HasStarted())
- {
- return HOST_E_INVALIDOPERATION;
- }
-
- // Both the type and assembly must be specified
- if (wszAppDomainManagerAssembly == NULL || wszAppDomainManagerType == NULL)
- {
- return E_INVALIDARG;
- }
-
- // Make sure we understand the incoming flags
- const EInitializeNewDomainFlags knownFlags = eInitializeNewDomainFlags_NoSecurityChanges;
- if ((dwInitializeDomainFlags & (~knownFlags)) != eInitializeNewDomainFlags_None)
- {
- return E_INVALIDARG;
- }
-
- // Get a copy of the AppDomainManager assembly
- size_t cchAsm = wcslen(wszAppDomainManagerAssembly) + 1;
- NewArrayHolder<WCHAR> wszAppDomainManagerAssemblyCopy(new (nothrow) WCHAR[cchAsm]);
- if (wszAppDomainManagerAssemblyCopy == NULL)
- {
- return E_OUTOFMEMORY;
- }
- wcsncpy_s(wszAppDomainManagerAssemblyCopy, cchAsm, wszAppDomainManagerAssembly, cchAsm - 1);
-
- // And of the AppDomainManagerType
- size_t cchType = wcslen(wszAppDomainManagerType) + 1;
- NewArrayHolder<WCHAR> wszAppDomainManagerTypeCopy(new (nothrow) WCHAR[cchType]);
- if (wszAppDomainManagerTypeCopy == NULL)
- {
- return E_OUTOFMEMORY;
- }
- wcsncpy_s(wszAppDomainManagerTypeCopy, cchType, wszAppDomainManagerType, cchType - 1);
-
- LPCWSTR wszOldAsmValue = FastInterlockCompareExchangePointer(&s_wszAppDomainManagerAsm,
- static_cast<LPCWSTR>(wszAppDomainManagerAssemblyCopy.GetValue()),
- NULL);
- if (wszOldAsmValue != NULL)
- {
- // We've tried to setup an AppDomainManager twice ... that's not allowed
- return HOST_E_INVALIDOPERATION;
- }
-
- s_wszAppDomainManagerType = wszAppDomainManagerTypeCopy;
- s_dwDomainManagerInitFlags = dwInitializeDomainFlags;
-
- wszAppDomainManagerAssemblyCopy.SuppressRelease();
- wszAppDomainManagerTypeCopy.SuppressRelease();
- return S_OK;
-}
-#endif // !FEATURE_CORECLR
LPCWSTR CorHost2::GetAppDomainManagerAsm()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return NULL;
-#else // FEATURE_CORECLR
- _ASSERTE (g_fEEStarted);
- return s_wszAppDomainManagerAsm;
-#endif // FEATURE_CORECLR
}
LPCWSTR CorHost2::GetAppDomainManagerType()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return NULL;
-#else // FEATURE_CORECLR
- _ASSERTE (g_fEEStarted);
- return s_wszAppDomainManagerType;
-#endif // FEATURE_CORECLR
}
// static
EInitializeNewDomainFlags CorHost2::GetAppDomainManagerInitializeNewDomainFlags()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return eInitializeNewDomainFlags_None;
-#else // FEAUTRE_CORECLR
- _ASSERTE (g_fEEStarted);
- return s_dwDomainManagerInitFlags;
-#endif // FEATURE_CORECLR
}
#ifdef FEATURE_INCLUDE_ALL_INTERFACES
#define DataToClrTlsInfo(a) (a)?(ClrTlsInfo*)((BYTE*)a - offsetof(ClrTlsInfo, data)):NULL
-#if !defined(FEATURE_CORECLR)
-#define HAS_FLS_SUPPORT 1
-#endif
#ifdef HAS_FLS_SUPPORT
}
#define ClrVirtualQuery EEVirtualQuery
-#if defined(_DEBUG) && defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#if defined(_DEBUG) && !defined(FEATURE_PAL)
static VolatilePtr<BYTE> s_pStartOfUEFSection = NULL;
static VolatilePtr<BYTE> s_pEndOfUEFSectionBoundary = NULL;
static Volatile<DWORD> s_dwProtection = 0;
//
// We assert if either of the two conditions above are true.
-#if defined(_DEBUG) && defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#if defined(_DEBUG) && !defined(FEATURE_PAL)
// We do this check in debug/checked builds only
// Do we have the UEF details?
};
#endif
-#ifdef FEATURE_CORECLR
HRESULT CorHost2::DllGetActivationFactory(DWORD appDomainID, LPCWSTR wszTypeName, IActivationFactory ** factory)
{
#ifdef FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION
return E_NOTIMPL;
#endif
}
-#endif
#ifdef FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION
AppDomain* pDomain = SystemDomain::System()->DefaultDomain();
_ASSERTE(pDomain);
-#ifndef FEATURE_CORECLR // coreclr uses winrt binder which does not allow redirects
- {
- BaseDomain::LockHolder lh(pDomain);
- if (!pDomain->HasLoadContextHostBinder())
- {
- // don't allow redirects
- SystemDomain::InitializeDefaultDomain(FALSE);
- }
- }
-#endif
BEGIN_EXTERNAL_ENTRYPOINT(&hr);
{
{
}
-#ifdef FEATURE_CORECLR
BOOL AppDomain::BindingByManifestFile()
{
return FALSE;
}
-#endif
ReJitManager::ReJitManager()
{
#else // !DACCESS_COMPILE
-#if !defined(FEATURE_CORECLR)
-// Slower spin enter path after first attemp failed
-void CrstBase::SpinEnter()
-{
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_NOTRIGGER;
- STATIC_CONTRACT_CAN_TAKE_LOCK;
-
- // We only reach this routine when first attemp failed, so time to fire ETW event (fyuan)
-
- // Fire an ETW event to mark the beginning of native contention
- FireEtwContentionStart_V1(ETW::ContentionLog::ContentionStructs::NativeContention, GetClrInstanceId());
-
- // Try spinning and yielding before eventually blocking.
- // The limit of dwRepetitions = 10 is largely arbitrary - feel free to tune if you have evidence
- // you're making things better.
-
- for (DWORD iter = 0; iter < g_SpinConstants.dwRepetitions; iter++)
- {
- DWORD i = g_SpinConstants.dwInitialDuration;
-
- do
- {
- if ( (m_criticalsection.LockCount == -1 ||
- (size_t)m_criticalsection.OwningThread == (size_t) GetCurrentThreadId())
- && UnsafeTryEnterCriticalSection(&m_criticalsection))
- {
- return;
- }
-
- if (g_SystemInfo.dwNumberOfProcessors <= 1)
- {
- break;
- }
-
- // Delay by approximately 2*i clock cycles (Pentium III).
- // This is brittle code - future processors may of course execute this
- // faster or slower, and future code generators may eliminate the loop altogether.
- // The precise value of the delay is not critical, however, and can't think
- // of a better way that isn't machine-dependent.
-
- for (int delayCount = i; --delayCount; )
- {
- YieldProcessor(); // indicate to the processor that we are spining
- }
-
- // exponential backoff: wait a factor longer in the next iteration
- i *= g_SpinConstants.dwBackoffFactor;
- } while (i < g_SpinConstants.dwMaximumDuration);
-
- __SwitchToThread(0, CALLER_LIMITS_SPINNING);
- }
-
- UnsafeEnterCriticalSection(& m_criticalsection);
-}
-#endif // FEATURE_CORECLR
void CrstBase::Enter(INDEBUG(NoLevelCheckFlag noLevelCheckFlag/* = CRST_LEVEL_CHECK*/))
if (! fIsCriticalSectionEnteredAfterFailingOnce)
{
-#ifndef FEATURE_CORECLR
- // Fire an ETW event to mark the beginning of native contention
- FireEtwContentionStart_V1(ETW::ContentionLog::ContentionStructs::NativeContention, GetClrInstanceId());
-#endif // !FEATURE_CORECLR
fIsCriticalSectionEnteredAfterFailingOnce = TRUE;
hr = m_pHostCrst->Enter(option);
Thread::BeginThreadAffinity();
}
-#ifdef FEATURE_CORECLR
UnsafeEnterCriticalSection(&m_criticalsection);
-#else
- // Try entering the critical section once, if we fail we contend
- // and fire the contention start ETW event
- if ((m_criticalsection.LockCount == -1 || (size_t)m_criticalsection.OwningThread == (size_t) GetCurrentThreadId())
- && UnsafeTryEnterCriticalSection(& m_criticalsection))
- {
- }
- else
- {
- SpinEnter();
-
- fIsCriticalSectionEnteredAfterFailingOnce = TRUE;
- }
-#endif
#ifdef FEATURE_INCLUDE_ALL_INTERFACES
INCTHREADLOCKCOUNTTHREAD(pThread);
#endif
}
-#ifndef FEATURE_CORECLR
- // Fire an ETW event to mark the end of native contention
- // This we do only when we have fired a contention start event before
- if (fIsCriticalSectionEnteredAfterFailingOnce)
- {
- FireEtwContentionStop(ETW::ContentionLog::ContentionStructs::NativeContention, GetClrInstanceId());
- }
-#endif // !FEATURE_CORECLR
#ifdef _DEBUG
PostEnter();
}
FCIMPLEND
-#ifdef FEATURE_CAS_POLICY
-FCIMPL4(VOID, COMCustomAttribute::GetSecurityAttributes, ReflectModuleBaseObject *pModuleUNSAFE, DWORD tkToken, CLR_BOOL fAssembly, PTRARRAYREF* ppArray)
-{
- FCALL_CONTRACT;
-
- OBJECTREF throwable = NULL;
- REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
-
- if(refModule == NULL)
- FCThrowResVoid(kArgumentNullException, W("Arg_InvalidHandle"));
-
- Module *pModule = refModule->GetModule();
-
- HELPER_METHOD_FRAME_BEGIN_2(throwable, refModule);
- {
- IMDInternalImport* pScope = pModule->GetMDImport();
-
- DWORD action;
-
- CORSEC_ATTRSET_ARRAY aAttrset;
- DWORD dwCount = 0;
- for(action = 1; action <= dclMaximumValue; action++)
- {
- // We cannot use IsAssemblyDclAction(action) != fAssembly because CLR_BOOL is defined
- // as BYTE in PAL so it might contain a value other than 0 or 1.
- if (IsNGenOnlyDclAction(action) || IsAssemblyDclAction(action) == !fAssembly)
- continue;
-
- HENUMInternalHolder hEnum(pScope);
- if (!hEnum.EnumPermissionSetsInit(tkToken, (CorDeclSecurity)action))
- continue;
-
- mdPermission tkPerm;
- BYTE* pbBlob;
- ULONG cbBlob;
- DWORD dwAction;
-
- while (pScope->EnumNext(&hEnum, &tkPerm))
- {
- IfFailThrow(pScope->GetPermissionSetProps(
- tkPerm,
- &dwAction,
- (void const **)&pbBlob,
- &cbBlob));
-
- CORSEC_ATTRSET* pAttrSet = &*aAttrset.Append();
- IfFailThrow(BlobToAttributeSet(pbBlob, cbBlob, pAttrSet, dwAction));
-
- dwCount += pAttrSet->dwAttrCount;
- }
- }
-
- *ppArray = (PTRARRAYREF)AllocateObjectArray(dwCount, g_pObjectClass);
-
- CQuickBytes qb;
-
- COUNT_T c = 0;
- for (COUNT_T i = 0; i < aAttrset.GetCount(); i ++)
- {
- CORSEC_ATTRSET& attrset = aAttrset[i];
- OBJECTREF* attrArray = (OBJECTREF*)qb.AllocThrows(attrset.dwAttrCount * sizeof(OBJECTREF));
- memset(attrArray, 0, attrset.dwAttrCount * sizeof(OBJECTREF));
- {
- // Convert to a managed array of attribute objects
- DWORD dwErrorIndex;
- HRESULT hr = E_FAIL;
- GCPROTECT_ARRAY_BEGIN(*attrArray, attrset.dwAttrCount);
- // This is very tricky.
- // We have a GCFrame local here. The local goes out of scope beyond for loop. The stack location of the local
- // is then reused by other variables, and the content in GCFrame may be changed. But the Frame is still chained
- // on our Thread object.
- // If exception is thrown before we pop our frame chain, we will have corrupted frame chain.
- hr = SecurityAttributes::AttributeSetToManaged(attrArray, &attrset, &throwable, &dwErrorIndex, true);
- GCPROTECT_END();
- if (FAILED(hr))
- COMPlusThrowHR(hr);
-
- for (COUNT_T j = 0; j < attrset.dwAttrCount; j ++)
- (*ppArray)->SetAt(c++, attrArray[j]);
- }
-
- }
- }
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-#endif // FEATURE_CAS_POLICY
FCIMPL7(void, COMCustomAttribute::GetPropertyOrFieldData, ReflectModuleBaseObject *pModuleUNSAFE, BYTE** ppBlobStart, BYTE* pBlobEnd, STRINGREF* pName, CLR_BOOL* pbIsProperty, OBJECTREF* pType, OBJECTREF* value)
{
DEFINE_DANGEROUS_API(EVENT, API_NAMES("AddEventHandler", "RemoveEventHandler", "ToString"))
DEFINE_DANGEROUS_API(RESOURCE_MANAGER, API_NAMES("GetResourceSet", "InternalGetResourceSet", ".ctor"))
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
-// The COM interfaces implemented by the reflection types.
-// The IDispatch Invoke methods are not included here because they are not implemented in mscorlib.
-DEFINE_DANGEROUS_API(ITYPE, API_NAMES("InvokeMember"))
-DEFINE_DANGEROUS_API(IASSEMBLY, API_NAMES("CreateInstance"))
-DEFINE_DANGEROUS_API(IMETHODBASE, API_NAMES("Invoke"))
-DEFINE_DANGEROUS_API(IMETHODINFO, API_NAMES("Invoke"))
-DEFINE_DANGEROUS_API(ICONSTRUCTORINFO, API_NAMES("Invoke", "Invoke_2", "Invoke_3", "Invoke_4", "Invoke_5"))
-DEFINE_DANGEROUS_API(IFIELDINFO, API_NAMES("GetValue", "SetValue"))
-DEFINE_DANGEROUS_API(IPROPERTYINFO, API_NAMES("GetValue", "SetValue"))
-DEFINE_DANGEROUS_API(IEVENTINFO, API_NAMES("AddEventHandler", "RemoveEventHandler"))
-DEFINE_DANGEROUS_API(IAPPDOMAIN, API_NAMES("CreateInstance", "CreateInstanceFrom", "DefineDynamicAssembly", "Load"))
-DEFINE_DANGEROUS_API(IREFLECT, API_NAMES("InvokeMember"))
-#endif // FEATURE_COMINTEROP && !FEATURE_CORECLR
m_pInternedStructures = new InternedStructureHashTable();
-#ifdef FEATURE_CORECLR
m_inlineTrackingMap = NULL;
-#else
- m_inlineTrackingMap = new InlineTrackingMap();
-#endif
}
DataImage::~DataImage()
return address;
}
-#ifndef FEATURE_CORECLR
-// Call into the unhandled-exception processing code to launch Watson.
-//
-// Arguments:
-// address - address to distinguish callsite of break.
-//
-// Notes:
-// Invokes a watson dialog in response to a user break (Debug.Break).
-// Assumes that caller has already enforced any policy it cares about related to whether a debugger is attached.
-void DoWatsonForUserBreak(UINT_PTR address)
-{
- CONTRACTL
- {
- MODE_ANY;
- GC_TRIGGERS;
- THROWS;
- PRECONDITION(address != NULL);
- }
- CONTRACTL_END;
-
- CONTEXT context;
- EXCEPTION_RECORD exceptionRecord;
- EXCEPTION_POINTERS exceptionPointers;
-
- ZeroMemory(&context, sizeof(context));
- ZeroMemory(&exceptionRecord, sizeof(exceptionRecord));
- ZeroMemory(&exceptionPointers, sizeof(exceptionPointers));
-
- // Try to locate the user managed code invoking System.Diagnostics.Debugger.Break
- UINT_PTR userCodeAddress = FindMostRecentUserCodeOnStack();
- if (userCodeAddress != NULL)
- {
- address = userCodeAddress;
- }
-
- LOG((LF_EH, LL_INFO10, "DoDebugBreak: break at %0p\n", address));
-
- exceptionRecord.ExceptionAddress = reinterpret_cast< PVOID >(address);
- exceptionPointers.ExceptionRecord = &exceptionRecord;
- exceptionPointers.ContextRecord = &context;
-
- Thread *pThread = GetThread();
- PTR_EHWatsonBucketTracker pUEWatsonBucketTracker = pThread->GetExceptionState()->GetUEWatsonBucketTracker();
- _ASSERTE(pUEWatsonBucketTracker != NULL);
- pUEWatsonBucketTracker->SaveIpForWatsonBucket(address);
- pUEWatsonBucketTracker->CaptureUnhandledInfoForWatson(TypeOfReportedError::UserBreakpoint, pThread, NULL);
- if (pUEWatsonBucketTracker->RetrieveWatsonBuckets() == NULL)
- {
- pUEWatsonBucketTracker->ClearWatsonBucketDetails();
- }
-
- WatsonLastChance(GetThread(), &exceptionPointers, TypeOfReportedError::UserBreakpoint);
-
-} // void DoDebugBreak()
-#endif // !FEATURE_CORECLR
// This does a user break, triggered by System.Diagnostics.Debugger.Break, or the IL opcode for break.
//
}
else
{
-#ifndef FEATURE_CORECLR
- // No debugger attached -- Watson up.
-
- // The HelperMethodFrame knows how to get the return address.
- DoWatsonForUserBreak(HELPER_METHOD_FRAME_GET_RETURN_ADDRESS());
-#endif //FEATURE_CORECLR
}
HELPER_METHOD_FRAME_END();
#define USE_COREDISTOOLS_DISASSEMBLER 0
#define USE_MSVC_DISASSEMBLER 0
#ifdef HAVE_GCCOVER
- #if defined(FEATURE_CORECLR)
// COREDISTOOLS disassembler only supports amd64 and x86, so if this is
// CoreCLR but not amd64 and not x86, we will fall out of this check and not
// set USE_DISASSEMBLER.
#undef USE_COREDISTOOLS_DISASSEMBLER
#define USE_COREDISTOOLS_DISASSEMBLER 1
#endif
- #elif defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
- #undef USE_MSVC_DISASSEMBLER
- #define USE_MSVC_DISASSEMBLER 1
- #endif // defined(FEATURE_CORECLR) || defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
#endif // HAVE_GCCOVER
#if USE_COREDISTOOLS_DISASSEMBLER
#include "eventtrace.h"
-#ifndef FEATURE_CORECLR
-#define NEEDDATA
-#include "fxretarget.h"
-#endif
#include "clr/fs/path.h"
using namespace clr::fs;
}
#endif // MDA_SUPPORTED
-#ifdef FEATURE_CORECLR
// For CoreClr, clear the last error before calling the target that returns last error.
// There isn't always a way to know the function have failed without checking last error,
// in particular on Unix.
{
pcsDispatch->EmitCALL(METHOD__STUBHELPERS__CLEAR_LAST_ERROR, 0, 0);
}
-#endif // FEATURE_CORECLR
// Invoke the target (calli, call method, call delegate, get/set field, etc.)
EmitInvokeTarget(pStubMD);
LOG((LF_STUBS, LL_INFO1000, "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"));
#endif // LOGGING
-#ifndef FEATURE_CORECLR
- //
- // Publish ETW events for IL stubs
- //
-
- // If the category and the event is enabled...
- if (ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, ILStubGenerated))
- {
- EtwOnILStubGenerated(
- pStubMD,
- pbLocalSig,
- cbSig,
- jitFlags,
- &convertToHRTryCatch,
- &cleanupTryFinally,
- maxStack,
- (DWORD)cbCode
- );
- }
-#endif // !FEATURE_CORECLR
}
-#ifndef FEATURE_CORECLR
- //---------------------------------------------------------------------------------------
- //
- void
- EtwOnILStubGenerated(
- MethodDesc * pStubMD,
- PCCOR_SIGNATURE pbLocalSig,
- DWORD cbSig,
- CORJIT_FLAGS jitFlags,
- ILStubEHClause * pConvertToHRTryCatchBounds,
- ILStubEHClause * pCleanupTryFinallyBounds,
- DWORD maxStack,
- DWORD cbCode)
- {
- STANDARD_VM_CONTRACT;
-
- //
- // Interop Method Information
- //
- MethodDesc *pTargetMD = m_slIL.GetTargetMD();
- SString strNamespaceOrClassName, strMethodName, strMethodSignature;
- UINT64 uModuleId = 0;
-
- if (pTargetMD)
- {
- pTargetMD->GetMethodInfoWithNewSig(strNamespaceOrClassName, strMethodName, strMethodSignature);
- uModuleId = (UINT64)pTargetMD->GetModule()->GetAddrModuleID();
- }
-
- //
- // Stub Method Signature
- //
- SString stubNamespaceOrClassName, stubMethodName, stubMethodSignature;
- pStubMD->GetMethodInfoWithNewSig(stubNamespaceOrClassName, stubMethodName, stubMethodSignature);
-
- IMDInternalImport *pStubImport = pStubMD->GetModule()->GetMDImport();
-
- CQuickBytes qbLocal;
- PrettyPrintSig(pbLocalSig, (DWORD)cbSig, NULL, &qbLocal, pStubImport, NULL);
-
- SString strLocalSig(SString::Utf8, (LPCUTF8)qbLocal.Ptr());
-
- //
- // Native Signature
- //
- SString strNativeSignature(SString::Utf8);
- if (m_dwStubFlags & NDIRECTSTUB_FL_REVERSE_INTEROP)
- {
- // Reverse interop. Use StubSignature
- strNativeSignature = stubMethodSignature;
- }
- else
- {
- // Forward interop. Use StubTarget siganture
- PCCOR_SIGNATURE pCallTargetSig = GetStubTargetMethodSig();
- DWORD cCallTargetSig = GetStubTargetMethodSigLength();
-
- CQuickBytes qbCallTargetSig;
-
- PrettyPrintSig(pCallTargetSig, cCallTargetSig, "", &qbCallTargetSig, pStubImport, NULL);
-
- strNativeSignature.SetUTF8((LPCUTF8)qbCallTargetSig.Ptr());
- }
-
- //
- // Dump IL stub code
- //
- SString strILStubCode;
- strILStubCode.Preallocate(4096); // Preallocate 4K bytes to avoid unnecessary growth
-
- SString codeSizeFormat;
- codeSizeFormat.LoadResource(CCompRC::Optional, IDS_EE_INTEROP_CODE_SIZE_COMMENT);
- strILStubCode.AppendPrintf(W("// %s\t%d (0x%04x)\n"), codeSizeFormat.GetUnicode(), cbCode, cbCode);
- strILStubCode.AppendPrintf(W(".maxstack %d \n"), maxStack);
- strILStubCode.AppendPrintf(W(".locals %s\n"), strLocalSig.GetUnicode());
-
- m_slIL.LogILStub(jitFlags, &strILStubCode);
-
- if (pConvertToHRTryCatchBounds->cbTryLength != 0 && pConvertToHRTryCatchBounds->cbHandlerLength != 0)
- {
- strILStubCode.AppendPrintf(
- W(".try IL_%04x to IL_%04x catch handler IL_%04x to IL_%04x\n"),
- pConvertToHRTryCatchBounds->dwTryBeginOffset,
- pConvertToHRTryCatchBounds->dwTryBeginOffset + pConvertToHRTryCatchBounds->cbTryLength,
- pConvertToHRTryCatchBounds->dwHandlerBeginOffset,
- pConvertToHRTryCatchBounds->dwHandlerBeginOffset + pConvertToHRTryCatchBounds->cbHandlerLength);
- }
-
- if (pCleanupTryFinallyBounds->cbTryLength != 0 && pCleanupTryFinallyBounds->cbHandlerLength != 0)
- {
- strILStubCode.AppendPrintf(
- W(".try IL_%04x to IL_%04x finally handler IL_%04x to IL_%04x\n"),
- pCleanupTryFinallyBounds->dwTryBeginOffset,
- pCleanupTryFinallyBounds->dwTryBeginOffset + pCleanupTryFinallyBounds->cbTryLength,
- pCleanupTryFinallyBounds->dwHandlerBeginOffset,
- pCleanupTryFinallyBounds->dwHandlerBeginOffset + pCleanupTryFinallyBounds->cbHandlerLength);
- }
-
- //
- // Fire the event
- //
- DWORD dwFlags = 0;
- if (m_dwStubFlags & NDIRECTSTUB_FL_REVERSE_INTEROP)
- dwFlags |= ETW_IL_STUB_FLAGS_REVERSE_INTEROP;
-#ifdef FEATURE_COMINTEROP
- if (m_dwStubFlags & NDIRECTSTUB_FL_COM)
- dwFlags |= ETW_IL_STUB_FLAGS_COM_INTEROP;
-#endif // FEATURE_COMINTEROP
- if (m_dwStubFlags & NDIRECTSTUB_FL_NGENEDSTUB)
- dwFlags |= ETW_IL_STUB_FLAGS_NGENED_STUB;
- if (m_dwStubFlags & NDIRECTSTUB_FL_DELEGATE)
- dwFlags |= ETW_IL_STUB_FLAGS_DELEGATE;
- if (m_dwStubFlags & NDIRECTSTUB_FL_CONVSIGASVARARG)
- dwFlags |= ETW_IL_STUB_FLAGS_VARARG;
- if (m_dwStubFlags & NDIRECTSTUB_FL_UNMANAGED_CALLI)
- dwFlags |= ETW_IL_STUB_FLAGS_UNMANAGED_CALLI;
-
- DWORD dwToken = 0;
- if (pTargetMD)
- dwToken = pTargetMD->GetMemberDef();
-
-
- //
- // Truncate string fields. Make sure the whole event is less than 64KB
- //
- TruncateUnicodeString(strNamespaceOrClassName, ETW_IL_STUB_EVENT_STRING_FIELD_MAXSIZE);
- TruncateUnicodeString(strMethodName, ETW_IL_STUB_EVENT_STRING_FIELD_MAXSIZE);
- TruncateUnicodeString(strMethodSignature, ETW_IL_STUB_EVENT_STRING_FIELD_MAXSIZE);
- TruncateUnicodeString(strNativeSignature, ETW_IL_STUB_EVENT_STRING_FIELD_MAXSIZE);
- TruncateUnicodeString(stubMethodSignature, ETW_IL_STUB_EVENT_STRING_FIELD_MAXSIZE);
- TruncateUnicodeString(strILStubCode, ETW_IL_STUB_EVENT_CODE_STRING_FIELD_MAXSIZE);
-
- //
- // Fire ETW event
- //
- FireEtwILStubGenerated(
- GetClrInstanceId(), // ClrInstanceId
- uModuleId, // ModuleIdentifier
- (UINT64)pStubMD, // StubMethodIdentifier
- dwFlags, // StubFlags
- dwToken, // ManagedInteropMethodToken
- strNamespaceOrClassName.GetUnicode(), // ManagedInteropMethodNamespace
- strMethodName.GetUnicode(), // ManagedInteropMethodName
- strMethodSignature.GetUnicode(), // ManagedInteropMethodSignature
- strNativeSignature.GetUnicode(), // NativeSignature
- stubMethodSignature.GetUnicode(), // StubMethodSigature
- strILStubCode.GetUnicode() // StubMethodILCode
- );
- } // EtwOnILStubGenerated
-#endif // !FEATURE_CORECLR
#ifdef LOGGING
//---------------------------------------------------------------------------------------
m_dwThreadLocalNum(-1),
m_dwCleanupWorkListLocalNum(-1),
m_dwRetValLocalNum(-1),
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
- m_dwFirstCopyCtorCookieLocalNum(-1),
- m_dwLastCopyCtorCookieLocalNum(-1),
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
m_ErrorResID(-1),
m_ErrorParamIdx(-1),
m_iLCIDParamIdx(iLCIDParamIdx),
pcsEmit->EmitLDLOCA(GetCleanupWorkListLocalNum());
}
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
-
-BOOL NDirectStubLinker::IsCopyCtorStubNeeded()
-{
- LIMITED_METHOD_CONTRACT;
- return (m_dwFirstCopyCtorCookieLocalNum != (DWORD)-1);
-}
-
-DWORD NDirectStubLinker::CreateCopyCtorCookie(ILCodeStream* pcsEmit)
-{
- STANDARD_VM_CONTRACT;
-
- MethodTable *pCookieMT = MscorlibBinder::GetClass(CLASS__COPYCTORSTUBCOOKIE);
-
- LocalDesc desc(pCookieMT);
- DWORD dwCookieLocalNum = pcsEmit->NewLocal(desc);
-
- // <dwCookieLocalNum> = new CopyCtorStubCookie()
- pcsEmit->EmitLDLOCA(dwCookieLocalNum);
- pcsEmit->EmitINITOBJ(pcsEmit->GetToken(pCookieMT));
-
- if (m_dwLastCopyCtorCookieLocalNum == (DWORD)-1)
- {
- // this is the first cookie in this stub
- m_dwFirstCopyCtorCookieLocalNum = dwCookieLocalNum;
- }
- else
- {
- // this is not the first cookie - build a linked list
- // <m_dwLastCopyCtorCookieLocalNum>.SetNext(&<dwCookieLocalNum>)
- pcsEmit->EmitLDLOCA(m_dwLastCopyCtorCookieLocalNum);
- pcsEmit->EmitLDLOCA(dwCookieLocalNum);
- pcsEmit->EmitCALL(METHOD__COPYCTORSTUBCOOKIE__SET_NEXT, 2, 0);
- }
-
- m_dwLastCopyCtorCookieLocalNum = dwCookieLocalNum;
- return dwCookieLocalNum;
-}
-
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
void NDirectStubLinker::Begin(DWORD dwStubFlags)
{
if (SF_IsForwardStub(dwStubFlags))
{
-#ifndef FEATURE_CORECLR // CAS
- // we may need to demand security permission
- if (SF_IsStubWithDemand(dwStubFlags))
- {
- if (SF_IsCOMStub(dwStubFlags) || SF_IsDelegateStub(dwStubFlags))
- {
- // pass NULL NDirectMethodDesc for COM and delegate P/Invoke
- m_pcsSetup->EmitLoadNullPtr();
- }
- else
- {
- // pass the real MD for direct P/Invoke
- EmitLoadStubContext(m_pcsSetup, dwStubFlags);
- }
- m_pcsSetup->EmitCALL(METHOD__STUBHELPERS__DEMAND_PERMISSION, 1, 0);
- }
-#endif // !FEATURE_CORECLR
if (SF_IsStubWithCctorTrigger(dwStubFlags))
{
if (SF_IsDelegateStub(dwStubFlags))
{
-#if defined(MDA_SUPPORTED) || (defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR))
+#if defined(MDA_SUPPORTED)
// GC was induced (gcUnmanagedToManagedMDA), arguments have been marshaled, and we are about
// to touch the UMEntryThunk and extract the delegate target from it so this is the right time
// to do the collected delegate MDA check.
STANDARD_VM_CONTRACT;
if (SF_IsForwardStub(dwStubFlags)) // managed-to-native
{
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
- // set the copy ctor cookie chain if needed
- if (IsCopyCtorStubNeeded())
- {
- // StubHelpers.SetCopyCtorCookieChain(pStubArg, pUnmngThis, dwStubFlags, &<m_dwFirstCopyCtorCookieLocalNum>)
- if (SF_IsDelegateStub(dwStubFlags))
- {
- // for forward delegate P/Invoke load the target from 'this'
- pcsEmit->EmitLoadThis();
- pcsEmit->EmitLDFLD(pcsEmit->GetToken(MscorlibBinder::GetField(FIELD__DELEGATE__METHOD_PTR_AUX)));
- }
- else
- {
- // otherwise load the secret argument
- EmitLoadStubContext(pcsEmit, dwStubFlags);
- }
-
- if (SF_IsCOMStub(dwStubFlags))
- {
- // for forward COM load the unmanaged interface pointer
- pcsEmit->EmitLDLOC(m_dwTargetInterfacePointerLocalNum);
- }
- else
- {
- // otherwise load 0
- pcsEmit->EmitLoadNullPtr();
- }
- pcsEmit->EmitLDC(dwStubFlags);
- pcsEmit->EmitLDLOCA(m_dwFirstCopyCtorCookieLocalNum);
- pcsEmit->EmitCALL(METHOD__STUBHELPERS__SET_COPY_CTOR_COOKIE_CHAIN, 4, 0);
- }
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
if (SF_IsDelegateStub(dwStubFlags)) // delegate invocation
{
#ifdef _TARGET_X86_
-#ifndef FEATURE_CORECLR
- if (IsCopyCtorStubNeeded())
- {
- // if we need to call copy ctor(s), we go to the copy ctor stub
- Stub *pCopyCtorStub = NDirect::GetStubForCopyCtor();
- pcsEmit->EmitLDC((DWORD_PTR)pCopyCtorStub->GetEntryPoint());
- }
- else
-#endif // !FEATURE_CORECLR
{
// for managed-to-unmanaged CALLI that requires marshaling, the target is passed
// as the secret argument to the stub by GenericPInvokeCalliHelper (asmhelpers.asm)
fMarshalReturnValueFirst = HasRetBuffArg(&msig);
#endif
-#if defined(_TARGET_AMD64_) && defined(_WIN64) && !defined(FEATURE_CORECLR)
- // JIT64 (which is only used on the Windows Desktop CLR) has a problem generating code
- // for the pinvoke ILStubs which do a return using a struct type. Therefore, we
- // change the signature of calli to return void and make the return buffer as first argument.
- // This matches the ABI i.e. return buffer is passed as first arg. So native target will get
- // the return buffer in correct register.
- // Ideally we only want to set it for JIT64 and not ryujit but currently there isn't a fast way
- // to determine that at runtime.
- fMarshalReturnValueFirst = HasRetBuffArg(&msig);
-#endif
}
if (fMarshalReturnValueFirst)
COMPlusThrow(kMarshalDirectiveException, IDS_EE_NDIRECT_BADNATL_THISCALL);
}
-#ifndef FEATURE_CORECLR
- if (info.GetMarshalType() == MarshalInfo::MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR)
- {
- fHasCopyCtorArgs = true;
- }
-#endif // !FEATURE_CORECLR
argidx++;
}
#ifdef _TARGET_X86_
-#ifndef FEATURE_CORECLR
- if (HasCopyCtorArgs())
- {
- _ASSERTE(pInterceptStub == NULL);
-
- // static stub that gets its arguments in a thread-static field
- pInterceptStub = NDirect::GetStubForCopyCtor();
- }
-#endif // !FEATURE_CORECLR
#ifdef MDA_SUPPORTED
if (!IsQCall() && MDA_GET_ASSISTANT(PInvokeStackImbalance))
}
}
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
-
-// Returns a small stub whose purpose is to record current ESP and call code:CopyCtorCallStubWorker
-// to invoke copy constructors and destructors as appropriate. This stub operates on arguments
-// already pushed to the stack by JITted IL stub and must not create a new frame, i.e. it must
-// tail call to the target for it to see the arguments that copy ctors have been called on.
-//
-// As a consequence, the stub doesn't take any extra secret arguments and the description of the
-// ctors/dtors to call is passed "out-of-band" in a thread static field. The worker returns
-// address of the real target (also passed out of band) which enables us to have only one static
-// stub in i386\asmhelpers.asm.
-
-// static
-Stub *NDirect::GetStubForCopyCtor()
-{
- STANDARD_VM_CONTRACT;
-
- static Stub *s_pStub = NULL;
-
- if (s_pStub == NULL)
- {
- Stub *pStub = Stub::NewStub(GetEEFuncEntryPoint(CopyCtorCallStub));
- if (InterlockedCompareExchangeT(&s_pStub, pStub, NULL) != NULL)
- {
- pStub->DecRef();
- }
- }
-
- s_pStub->IncRef();
- return s_pStub;
-}
-
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
#ifdef FEATURE_INCLUDE_ALL_INTERFACES
BOOL NDirect::IsHostHookEnabled()
}
#endif // _TARGET_X86_ && MDA_SUPPORTED
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
-struct CopyCtorStubCookie // same layout as StubHelpers.CopyCtorStubCookie
-{
- LPVOID m_srcInstancePtr;
- DWORD m_dstStackOffset;
- LPVOID m_ctorPtr; // managed method ptr
- LPVOID m_dtorPtr; // managed method ptr
-
- CopyCtorStubCookie *m_pNext;
-};
-
-struct CopyCtorStubDesc // same layout as StubHelpers.CopyCtorStubDesc
-{
- CopyCtorStubCookie *m_pCookie;
- LPVOID m_pTarget;
-};
-
-// Called by CopyCtorCallStub after we have already transitioned to unmanaged. Invokes copy ctor(s)
-// and dtor(s) using reverse P/Invoke which has some perf impact but provides all the debugging and
-// profiling support. An alternative solution would be CallDescr or some optimized variant of it
-// which would probably result in confusing call stacks.
-EXTERN_C LPVOID __stdcall CopyCtorCallStubWorker(BYTE *pESP)
-{
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_MODE_PREEMPTIVE; // we've already switched to preemptive
-
- CopyCtorStubCookie *pCookie;
- LPVOID pTarget;
- {
- GCX_COOP();
- // get address of the thread-static field
- FieldDesc *pFD = MscorlibBinder::GetField(FIELD__STUBHELPERS__COPY_CTOR_STUB_DESC);
-
- CopyCtorStubDesc *pStubDesc = (CopyCtorStubDesc *)Thread::GetStaticFieldAddress(pFD);
-
- // read the fields in cooperative mode
- pCookie = pStubDesc->m_pCookie;
- pTarget = pStubDesc->m_pTarget;
-
- _ASSERTE(pCookie != NULL && pTarget != NULL);
-
- // make sure we ASSERT/AV reliably if we are called by mistake
- pStubDesc->m_pCookie = NULL;
- pStubDesc->m_pTarget = NULL;
- }
-
- while (pCookie != NULL)
- {
- if (pCookie->m_ctorPtr != NULL)
- {
- // get reverse P/Invoke to the copy ctor (cache on AD)
- MethodDesc *pMD = Entry2MethodDesc((PCODE)pCookie->m_ctorPtr, NULL);
- UMEntryThunk *pUMEntryThunk = GetAppDomain()->GetUMEntryThunkCache()->GetUMEntryThunk(pMD);
-
- // GetUMEntryThunk always returns stdcall-able function pointers for ordinary managed methods
- // but the ctor can be a P/Invoke (pre-Whidbey MC++ only)
- typedef void (__stdcall *CtorFnPtr_StdCall) (LPVOID dst, LPVOID src);
- typedef void (__thiscall *CtorFnPtr_ThisCall)(LPVOID dst, LPVOID src);
- typedef void (__cdecl *CtorFnPtr_Cdecl) (LPVOID dst, LPVOID src);
-
- // call the copy ctor using the right calling convention
- UMThunkMarshInfo *pMarshInfo = pUMEntryThunk->GetUMThunkMarshInfo();
- pMarshInfo->RunTimeInit();
-
- switch (pMarshInfo->GetCallingConvention() & pmCallConvMask)
- {
- case pmCallConvStdcall:
- case pmCallConvWinapi:
- {
- CtorFnPtr_StdCall fnPtr = (CtorFnPtr_StdCall)pUMEntryThunk->GetCode();
- fnPtr(pESP + pCookie->m_dstStackOffset, pCookie->m_srcInstancePtr);
- break;
- }
-
- case pmCallConvThiscall:
- {
- CtorFnPtr_ThisCall fnPtr = (CtorFnPtr_ThisCall)pUMEntryThunk->GetCode();
- fnPtr(pESP + pCookie->m_dstStackOffset, pCookie->m_srcInstancePtr);
- break;
- }
-
- default:
- {
- _ASSERTE((pMarshInfo->GetCallingConvention() & pmCallConvMask) == pmCallConvCdecl);
-
- CtorFnPtr_Cdecl fnPtr = (CtorFnPtr_Cdecl)pUMEntryThunk->GetCode();
- fnPtr(pESP + pCookie->m_dstStackOffset, pCookie->m_srcInstancePtr);
- break;
- }
- }
- }
- if (pCookie->m_dtorPtr != NULL)
- {
- // get reverse P/Invoke to the dtor (cache on AD)
- MethodDesc *pMD = Entry2MethodDesc((PCODE)pCookie->m_dtorPtr, NULL);
- UMEntryThunk *pUMEntryThunk = GetAppDomain()->GetUMEntryThunkCache()->GetUMEntryThunk(pMD);
-
- // GetUMEntryThunk always returns stdcall-able function pointers for ordinary managed methods
- // but the dtor can be a P/Invoke (pre-Whidbey MC++ only)
- typedef void (__stdcall *DtorFnPtr_StdCall) (LPVOID src);
- typedef void (__thiscall *DtorFnPtr_ThisCall)(LPVOID src);
- typedef void (__cdecl *DtorFnPtr_Cdecl) (LPVOID src);
-
- // call the dtor using the right calling convention
- UMThunkMarshInfo *pMarshInfo = pUMEntryThunk->GetUMThunkMarshInfo();
- pMarshInfo->RunTimeInit();
-
- switch (pMarshInfo->GetCallingConvention() & pmCallConvMask)
- {
- case pmCallConvStdcall:
- case pmCallConvWinapi:
- {
- DtorFnPtr_StdCall fnPtr = (DtorFnPtr_StdCall)pUMEntryThunk->GetCode();
- fnPtr(pCookie->m_srcInstancePtr);
- break;
- }
-
- case pmCallConvThiscall:
- {
- DtorFnPtr_ThisCall fnPtr = (DtorFnPtr_ThisCall)pUMEntryThunk->GetCode();
- fnPtr(pCookie->m_srcInstancePtr);
- break;
- }
-
- default:
- {
- _ASSERTE((pMarshInfo->GetCallingConvention() & pmCallConvMask) == pmCallConvCdecl);
-
- DtorFnPtr_Cdecl fnPtr = (DtorFnPtr_Cdecl)pUMEntryThunk->GetCode();
- fnPtr(pCookie->m_srcInstancePtr);
- break;
- }
- }
- }
- pCookie = pCookie->m_pNext;
- }
-
- return pTarget;
-}
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
// Preserving good error info from DllImport-driven LoadLibrary is tricky because we keep loading from different places
// if earlier loads fail and those later loads obliterate error codes.
#define TOLOWER(a) (((a) >= W('A') && (a) <= W('Z')) ? (W('a') + (a - W('A'))) : (a))
#define TOHEX(a) ((a)>=10 ? W('a')+(a)-10 : W('0')+(a))
-#ifndef FEATURE_CORECLR
-/*static*/
-VOID NDirect::CheckUnificationList(NDirectMethodDesc * pMD, DWORD * pDllImportSearchPathFlag, BOOL * pSearchAssemblyDirectory)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // If neither assembly and method have the attribute, check the unification list.
- Assembly *pAssembly = pMD->GetAssembly();
-
- if (!pAssembly->IsStrongNamed())
- return;
-
- const char * simpleName = pAssembly->GetSimpleName();
-
- StringHashIterator(it, g_arFxPolicy, simpleName);
-
- int pos;
-
- while ((pos = it.GetNext()) >= 0)
- {
- const FrameworkConfig & config = g_arFxPolicy[pos];
-
- FixedSizeString<char> asmName;
-
- config.GetFxAssemblyName(asmName);
-
- if (_stricmp(asmName, simpleName) == 0)
- {
- DWORD cbPublicKey = 0;
- const void *pbPublicKey = NULL;
- pbPublicKey = pAssembly->GetPublicKey(&cbPublicKey);
-
- //
- // StrongNameTokenFromPublicKey is potentially expensive operation. Do it only once we got a match on the simple name.
- //
- StrongNameBufferHolder<BYTE> pbStrongNameToken;
- DWORD cbStrongNameToken;
-
- if (StrongNameTokenFromPublicKey((BYTE*) pbPublicKey,cbPublicKey,&pbStrongNameToken,&cbStrongNameToken))
- {
- BOOL pktIsEqual = TRUE;
-
- LPCWSTR pwzPKT = config.GetPKT();
-
- for (UINT j = 0; j < cbStrongNameToken; j++)
- {
- WCHAR firstChar = TOHEX(pbStrongNameToken[j] / 16);
- WCHAR secondChar = TOHEX(pbStrongNameToken[j] % 16);
-
- if (firstChar != TOLOWER(pwzPKT[j*2]) || secondChar != TOLOWER(pwzPKT[j*2+1]))
- {
- pktIsEqual = FALSE;
- break;
- }
- }
-
- if (pktIsEqual)
- {
- *pDllImportSearchPathFlag = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS;
- *pSearchAssemblyDirectory = TRUE;
- break;
- }
- }
- }
- }
-}
-#endif // !FEATURE_CORECLR
// static
HMODULE NDirect::LoadLibraryFromPath(LPCWSTR libraryPath)
return hmod;
}
-#ifdef FEATURE_CORECLR
// Try to load the module from the native DLL search directories
HMODULE NDirect::LoadFromNativeDllSearchDirectories(AppDomain* pDomain, LPCWSTR libName, DWORD flags, LoadLibErrorTracker *pErrorTracker)
{
return hmod;
}
-#endif // FEATURE_CORECLR
HINSTANCE NDirect::LoadLibraryModule(NDirectMethodDesc * pMD, LoadLibErrorTracker * pErrorTracker)
{
}
#endif // FEATURE_CORESYSTEM && !FEATURE_PAL
-#ifdef FEATURE_CORECLR
if (hmod == NULL)
{
// NATIVE_DLL_SEARCH_DIRECTORIES set by host is considered well known path
hmod = LoadFromNativeDllSearchDirectories(pDomain, wszLibName, loadWithAlteredPathFlags, pErrorTracker);
}
-#endif // FEATURE_CORECLR
DWORD dllImportSearchPathFlag = 0;
BOOL searchAssemblyDirectory = TRUE;
}
}
-#ifndef FEATURE_CORECLR
- if (!attributeIsFound)
- {
- CheckUnificationList(pMD, &dllImportSearchPathFlag, &searchAssemblyDirectory);
- }
-#endif
if (!libNameIsRelativePath)
{
Assembly* pAssembly = pMD->GetMethodTable()->GetAssembly();
hmod = LoadFromPInvokeAssemblyDirectory(pAssembly, wszLibName, loadWithAlteredPathFlags | dllImportSearchPathFlag, pErrorTracker);
-#ifndef FEATURE_CORECLR
- if (hmod == NULL)
- {
- // Try to load the DLL alongside the assembly where the PInvoke was
- // declared using the codebase of the assembly. This is required for download
- // and shadow copy scenarios.
- const WCHAR* ptr;
- SString codebase;
- pAssembly->GetCodeBase(codebase);
- DWORD dwCodebaseLength = codebase.GetCount();
-
- // Strip off the protocol
- for (ptr = codebase.GetUnicode(); *ptr && *ptr != W(':'); ptr++);
-
- // If we have a code base then prepend it to the library name
- if (*ptr)
- {
- SString pathFromCodebase;
-
- // After finding the colon move forward until no more forward slashes
- for (ptr++; *ptr && *ptr == W('/'); ptr++);
- if (*ptr)
- {
- // Calculate the number of characters we are interested in
- if (dwCodebaseLength > (DWORD)(ptr - codebase.GetUnicode()) )
- {
- // Back up to the last slash (forward or backwards)
- const WCHAR* tail;
-
- for (tail = codebase.GetUnicode() + (dwCodebaseLength - 1); tail > ptr && *tail != W('/') && *tail != W('\\'); tail--);
-
- if (tail > ptr)
- {
- for (;ptr <= tail; ptr++)
- {
- if (*ptr == W('/'))
- pathFromCodebase.Append(W('\\'));
- else
- pathFromCodebase.Append(*ptr);
- }
- }
- }
- }
-
- pathFromCodebase.Append(wszLibName);
-
- SString path = pAssembly->GetManifestFile()->GetPath();
- SString::Iterator i = path.End();
- if (PEAssembly::FindLastPathSeparator(path, i))
- {
- i++;
- path.Truncate(i);
- path.Append(wszLibName);
- }
-
- if (!pathFromCodebase.EqualsCaseInsensitive(path, PEImage::GetFileSystemLocale()))
- {
- hmod = LocalLoadLibraryHelper(pathFromCodebase, loadWithAlteredPathFlags | dllImportSearchPathFlag, pErrorTracker);
- }
- }
- }
-#endif // !FEATURE_CORECLR
}
}
}
CONTRACTL_END;
-#if !defined(FEATURE_CORECLR)
- // Generate a table of some well known native dlls
- s_pWellKnownNativeModules = ::new PtrHashMap();
- s_pWellKnownNativeModules->Init(sizeof(wellKnownModules)/sizeof(LPCWSTR), CompareLibNames, TRUE, NULL);
- for (int index = 0; index < sizeof(wellKnownModules)/sizeof(LPCWSTR); index++)
- {
- s_pWellKnownNativeModules->InsertValue((UPTR) HashiString(wellKnownModules[index]), (LPVOID)wellKnownModules[index]);
- }
-
- // Check if the OS supports the new secure LoadLibraryEx flags introduced in KB2533623
- HMODULE hMod = CLRGetModuleHandle(WINDOWS_KERNEL32_DLLNAME_W);
- _ASSERTE(hMod != NULL);
-
- if (GetProcAddress(hMod, "AddDllDirectory") != NULL)
- {
- // The AddDllDirectory export was added in KB2533623 together with the new flag support
- s_fSecureLoadLibrarySupported = true;
- }
-#endif // !FEATURE_CORECLR
}
static HMODULE LoadLibraryFromPath(LPCWSTR libraryPath);
static HINSTANCE LoadLibraryModule(NDirectMethodDesc * pMD, LoadLibErrorTracker *pErrorTracker);
-#ifndef FEATURE_CORECLR
- static VOID CheckUnificationList(NDirectMethodDesc * pMD, DWORD * pDllImportSearchPathFlag, BOOL * pSearchAssemblyDirectory);
-#endif // !FEATURE_CORECLR
static VOID NDirectLink(NDirectMethodDesc *pMD);
inline static ILStubCache* GetILStubCache(NDirectStubParameters* pParams);
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
- static Stub* GetStubForCopyCtor();
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
static BOOL IsHostHookEnabled();
private:
NDirect() {LIMITED_METHOD_CONTRACT;}; // prevent "new"'s on this class
-#ifdef FEATURE_CORECLR
static HMODULE LoadFromNativeDllSearchDirectories(AppDomain* pDomain, LPCWSTR libName, DWORD flags, LoadLibErrorTracker *pErrorTracker);
-#endif
static HMODULE LoadFromPInvokeAssemblyDirectory(Assembly *pAssembly, LPCWSTR libName, DWORD flags, LoadLibErrorTracker *pErrorTracker);
#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
void GetCleanupFinallyOffsets(ILStubEHClause * pClause);
void AdjustTargetStackDeltaForReverseInteropHRESULTSwapping();
void AdjustTargetStackDeltaForExtraParam();
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
- DWORD CreateCopyCtorCookie(ILCodeStream* pcsEmit);
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
void SetInteropParamExceptionInfo(UINT resID, UINT paramIdx);
bool HasInteropParamExceptionInfo();
void InitCleanupCode();
void InitExceptionCleanupCode();
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
- BOOL IsCopyCtorStubNeeded();
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
ILCodeStream* m_pcsSetup;
DWORD m_dwCleanupWorkListLocalNum;
DWORD m_dwRetValLocalNum;
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
- DWORD m_dwFirstCopyCtorCookieLocalNum; // list head passed to SetCopyCtorCookieChain
- DWORD m_dwLastCopyCtorCookieLocalNum; // used for chaining the cookies into a linked list
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
UINT m_ErrorResID;
UINT m_ErrorParamIdx;
#include "umthunkhash.h"
#include "peimagelayout.inl"
-#if !defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
-#include "policy.h" // for fusion::util::isanyframeworkassembly
-#endif
#include "winrthelpers.h"
#ifdef FEATURE_PERFMAP
if (pDependency->signNativeImage == INVALID_NGEN_SIGNATURE)
continue;
-#ifdef FEATURE_CORECLR // hardbinding
//
// CoreCLR hard binds to mscorlib.dll only. Avoid going through the full load.
PEAssembly * pDependencyFile = SystemDomain::SystemFile();
-#else // FEATURE_CORECLR
-
- //
- // Load the manifest file for the given name assembly spec.
- //
-
- AssemblySpec name;
- name.InitializeSpec(pDependency->dwAssemblyRef,
- ((pManifestNativeImage != NULL) ? pManifestNativeImage : pNativeImage)->GetNativeMDImport(),
- GetDomainAssembly());
-
- if (this->GetAppDomain()->IsCompilationDomain())
- {
- //
- // Allow transitive closure of hardbound dependecies to be loaded during ngen.
- //
-
- DomainAssembly * pDependencyAssembly = name.LoadDomainAssembly(FILE_LOAD_FIND_NATIVE_IMAGE);
- pDependencyAssembly->GetFile()->SetSafeToHardBindTo();
- }
-
- DomainAssembly * pDependencyAssembly = NULL;
- {
- // We are about to validate the hard-bound dependencies of the assembly being loaded. The invariant of being hard-bound states
- // that each hard-bound dependency must have its NI image to be valid and available for loading and this is done recursively for each
- // hard-bound dependency.
- //
- // The validity (and presence) of the NI image happens in FILE_LOAD_ALLOCATE stage of assembly load, which is the next stage in assembly loading,
- // and not the current stage (FILE_LOAD_VERIFY_NATIVE_DEPENDENCIES). In FILE_LOAD_ALLOCATE, we do sharing checks, closure validation, redirection policy application, etc
- // before computing if a NI is available and if it is, whether it is valid or not.
- //
- // However, we need to know about validity of NI in the current(and earlier) stage. As a result, we will temporarily set the assembly load limit (defined as the maximum
- // load level till which recursive assembly load can execute) to be FILE_LOAD_ALLOCATE if we have been invoked to validate the NI dependencies for the first time.
- //
- // A valid concern at this point is that we would allow to load a dependency at a load stage higher than its dependent assembly as it could crete cycles. This concern is
- // alleviated since we are doing this override (of the load stage) only for hard-bound dependencies and NGEN is responsible for ensuring that there are no cycles.
- //
- // As a result, once the dependency load returns, we will know for sure if the dependency has a valid NI or not.
- OVERRIDE_LOAD_LEVEL_LIMIT(verifyOnly ? FILE_LOADED : FILE_LOAD_ALLOCATE);
- pDependencyAssembly = name.LoadDomainAssembly(FILE_LOADED);
- }
-
- PEAssembly * pDependencyFile = pDependencyAssembly->GetFile();
-
-#endif // FEATURE_CORECLR
ReleaseHolder<PEImage> pDependencyNativeImage = pDependencyFile->GetNativeImageWithRef();
if (pDependencyNativeImage == NULL)
#ifdef FEATURE_PREJIT
-#ifdef FEATURE_CORECLR // hardbinding
//
// CoreCLR hard binds to mscorlib.dll only. No need to track hardbound dependencies.
//
-#else
- // Add hard bindings as unconditional dependencies
- if (GetFile()->HasNativeImage() && GetCurrentModule()->HasNativeImage() && IsAssembly())
- {
- PEImage *pNativeImage = GetFile()->GetPersistentNativeImage();
- PEImageLayout *pNativeLayout = pNativeImage->GetLoadedLayout();
-
- COUNT_T cDependencies;
- CORCOMPILE_DEPENDENCY *pDependencies = pNativeLayout->GetNativeDependencies(&cDependencies);
- CORCOMPILE_DEPENDENCY *pDependenciesEnd = pDependencies + cDependencies;
-
- while (pDependencies < pDependenciesEnd)
- {
- if (pDependencies->signNativeImage != INVALID_NGEN_SIGNATURE)
- {
-
- //
- // Load the manifest file for the given name assembly spec.
- //
-
- AssemblySpec name;
- name.InitializeSpec(pDependencies->dwAssemblyRef,
- pNativeImage->GetNativeMDImport(),
- GetDomainAssembly());
-
- DomainAssembly *pDependency = name.LoadDomainAssembly(FILE_LOADED);
-
- // Right now we only support hard binding to other manifest modules so we don't
- // need to consider the other module cases
- Module *pModule = pDependency->GetModule();
-
- // Add hard binding as an unconditional active dependency
- STRESS_LOG4(LF_CODESHARING,LL_INFO100,"unconditional dependency %p %p %i %i\n",
- GetFile(),GetCurrentModule(),GetFile()->HasNativeImage(),GetCurrentModule()->HasNativeImage());
- if(!pModule->IsSystem())
- GetCurrentModule()->AddActiveDependency(pModule, TRUE);
- }
-
- pDependencies++;
- }
- }
-#endif // FEATURE_CORECLR
#endif // FEATURE_PREJIT
}
// Are we absolutely required to use a native image?
CheckZapRequired();
-#if defined(FEATURE_CORECLR) && defined(FEATURE_COMINTEROP)
+#if defined(FEATURE_COMINTEROP)
// If this is a winmd file, ensure that the ngen reference namespace is loadable.
// This is necessary as on the phone we don't check ngen image dependencies, and thus we can get in a situation
// where a winmd is loaded as a dependency of an ngen image, but the type used to build cross module references
m_bDisableActivationCheck=TRUE;
pMT->CheckRunClassInitThrowing();
}
-#ifdef FEATURE_CORECLR
if (g_pConfig->VerifyModulesOnLoad())
{
m_pModule->VerifyAllMethods();
}
-#endif //FEATURE_CORECLR
#ifdef _DEBUG
if (g_pConfig->ExpandModulesOnLoad())
{
if (pLoadSecurity != NULL)
{
-#ifdef FEATURE_CAS_POLICY
- // If this assembly had a file name specified, we aren't allowed to load from remote sources and we
- // aren't in CAS policy mode (which sandboxes remote assemblies automatically), then we need to do a
- // check on this assembly's zone of origin when creating it.
- if (pLoadSecurity->m_fCheckLoadFromRemoteSource &&
- !pLoadSecurity->m_fSuppressSecurityChecks &&
- !m_pDomain->GetSecurityDescriptor()->AllowsLoadsFromRemoteSources() &&
- !pFile->IsIntrospectionOnly())
- {
- SString strCodeBase;
- BYTE pbUniqueID[MAX_SIZE_SECURITY_ID];
- DWORD cbUniqueID = COUNTOF(pbUniqueID);
- SecZone dwZone = NoZone;
-
- GetSecurityIdentity(strCodeBase,
- &dwZone,
- 0,
- pbUniqueID,
- &cbUniqueID);
-
- // Since loads from remote sources are not enabled for this assembly, we only want to allow the
- // load if any of the following conditions apply:
- //
- // * The load is coming off the local machine
- // * The load is coming from the intranet or a trusted site, and the code base is UNC. (ie,
- // don't allow HTTP loads off the local intranet
-
- bool safeLoad = false;
- if (dwZone == LocalMachine)
- {
- safeLoad = true;
- }
- else if (dwZone == Intranet || dwZone == Trusted)
- {
- if (UrlIsFileUrl(strCodeBase.GetUnicode()))
- {
- safeLoad = true;
- }
- else if (PathIsUNC(strCodeBase.GetUnicode()))
- {
- safeLoad = true;
- }
- }
-
- if (!safeLoad)
- {
- // We've tried to load an assembly from a location where it would have been sandboxed in legacy
- // CAS situations, but the application hasn't indicated that this is a safe thing to do. In
- // order to prevent accidental security holes by silently loading assemblies in full trust that
- // an application expected to be sandboxed, we'll throw an exception instead.
- //
- // Since this exception can commonly occur with if the file is physically located on the
- // hard drive, but has the mark of the web on it we'll also try to detect this mark and
- // provide a customized error message if we find it. We do that by re-evaluating the
- // assembly's zone with the NOSAVEDFILECHECK flag, which ignores the mark of the web, and if
- // that comes back as MyComputer we flag the assembly as having the mark of the web on it.
- SecZone dwNoMotwZone = NoZone;
- GetSecurityIdentity(strCodeBase, &dwNoMotwZone, MUTZ_NOSAVEDFILECHECK, pbUniqueID, &cbUniqueID);
-
- if (dwNoMotwZone == LocalMachine)
- {
- COMPlusThrow(kNotSupportedException, IDS_E_LOADFROM_REMOTE_SOURCE_MOTW);
- }
- else
- {
- COMPlusThrow(kNotSupportedException, IDS_E_LOADFROM_REMOTE_SOURCE);
- }
- }
- }
-#endif // FEATURE_CAS_POLICY
if (GetFile()->IsSourceGAC())
{
{
GCX_COOP();
-#ifdef FEATURE_CAS_POLICY
- if (pLoadSecurity->m_pAdditionalEvidence != NULL)
- {
- if(*pLoadSecurity->m_pAdditionalEvidence != NULL)
- {
- pSecurityDescriptorHolder->SetAdditionalEvidence(*pLoadSecurity->m_pAdditionalEvidence);
- }
- }
- else if (pLoadSecurity->m_pEvidence != NULL)
- {
- if (*pLoadSecurity->m_pEvidence != NULL)
- {
- pSecurityDescriptorHolder->SetEvidence(*pLoadSecurity->m_pEvidence);
- }
- }
-#endif // FEATURE_CAS_POLICY
// If the assembly being loaded already knows its grant set (for instnace, it's being pushed
// from the loading assembly), then we can set that up now as well
{
_ASSERTE(pLoadSecurity->m_pGrantSet != NULL);
-#ifdef FEATURE_CAS_POLICY
- // The permissions from an anonymously hosted dynamic method are fulltrust/transparent,
- // so ensure we have full trust to pass that on to the new assembly
- if(pLoadSecurity->m_fPropagatingAnonymouslyHostedDynamicMethodGrant &&
- !CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_Security_DisableAnonymouslyHostedDynamicMethodCreatorSecurityCheck))
- {
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_FULL_TRUST);
- }
-#endif // FEATURE_CAS_POLICY
pSecurityDescriptorHolder->PropagatePermissionSet(
*pLoadSecurity->m_pGrantSet,
return m_MissingDependenciesCheckStatus != CMD_Unknown;
}
-#ifdef FEATURE_CORECLR
CMD_State DomainAssembly::CheckMissingDependencies()
{
//CoreCLR simply doesn't share if dependencies are missing
return CMD_NotNeeded;
}
-#endif // FEATURE_CORECLR
#endif // FEATURE_LOADER_OPTIMIZATION
}
#endif // FEATURE_TREAT_NI_AS_MSIL_DURING_DIAGNOSTICS
-#ifndef FEATURE_CORECLR // hardbinding
- // The IsSafeToHardBindTo() check is only for use during the ngen compilation phase. It discards ngen images for
- // assemblies that aren't hard-bound to (as this would cause all such assemblies be loaded eagerly.)
- if (!IsSystem() && this->GetAppDomain()->IsCompilationDomain() && !GetFile()->IsSafeToHardBindTo())
- {
- if (!this->GetAppDomain()->ToCompilationDomain()->IsSafeToHardBindTo(GetFile()))
- {
- GetFile()->SetCannotUseNativeImage();
-
- if (GetFile()->HasNativeImage())
- GetFile()->ClearNativeImage();
-
- return;
- }
-
- GetFile()->SetSafeToHardBindTo();
- }
-#endif
#ifdef FEATURE_FUSION
DomainAssembly * pDomainAssembly = GetDomainAssembly();
if (GetFile()->HasNativeImage())
{
-#if defined(_DEBUG) && defined(FEATURE_CORECLR)
+#if defined(_DEBUG)
if (g_pConfig->ForbidZap(GetSimpleName()))
{
SString sbuf;
}
}
-#if defined(FEATURE_CORECLR)
if (!GetFile()->HasNativeImage())
{
//
GetAppDomain()->CheckForMismatchedNativeImages(&spec, &mvid);
}
-#endif
CheckZapRequired();
}
#ifdef FEATURE_LOADER_OPTIMIZATION
-#ifndef FEATURE_CORECLR
-
- BOOL fIsShareableHostAssembly = FALSE;
- if (GetFile()->HasHostAssembly())
- {
- IfFailThrow(GetFile()->GetHostAssembly()->IsShareable(&fIsShareableHostAssembly));
- }
-
-#ifdef FEATURE_FUSION
- // Only use domain neutral code for normal assembly loads
- if ((GetFile()->GetFusionAssembly() == NULL) && !fIsShareableHostAssembly)
- {
- return FALSE;
- }
-#endif
-
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
- // Introspection only does not use domain neutral code
- if (IsIntrospectionOnly())
- return FALSE;
-#endif
-
-#ifdef FEATURE_FUSION
- // use domain neutral code only for Load context, as the
- // required eager binding interferes with LoadFrom binding semantics
- if (!GetFile()->IsContextLoad() && !fIsShareableHostAssembly)
- return FALSE;
-#endif
-
- // Check app domain policy...
- if (this->GetAppDomain()->ApplySharePolicy(this))
- {
- if (IsSystem())
- return TRUE;
-
- // if not the default AD, ensure that the closure is filled in
- if (this->GetAppDomain() != SystemDomain::System()->DefaultDomain())
- GetAssemblyBindingClosure(LEVEL_COMPLETE);
-
-
- // Can be domain neutral only if we aren't binding any missing dependencies with
- // the assembly resolve event
- if ((this->GetAppDomain() != SystemDomain::System()->DefaultDomain()) &&
- (CheckMissingDependencies() == CMD_Resolved))
- {
- return FALSE;
- }
-
- // Ensure that all security conditions are met for code sharing
- if (!Security::CanShareAssembly(this))
- {
- return FALSE;
- }
-
- return TRUE;
- }
- return FALSE;
-
-#else // FEATURE_CORECLR
if (IsSystem())
return TRUE;
return FALSE; // No meaning in doing costly closure walk for CoreCLR.
-#endif // FEATURE_CORECLR
#else // FEATURE_LOADER_OPTIMIZATION
return IsSystem();
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
// Do not store runtime timestamps into NGen image for cross-platform NGen determinism
-#else
- // fill in pRuntimeDllInfo
- CORCOMPILE_RUNTIME_DLL_INFO *pRuntimeDllInfo = pNativeVersionInfo->runtimeDllInfo;
-
- for (DWORD index = 0; index < NUM_RUNTIME_DLLS; index++)
- {
-#ifdef CROSSGEN_COMPILE
- SString sFileName(SString::Utf8, CorCompileGetRuntimeDllName((CorCompileRuntimeDlls)index));
-
- PEImageHolder pImage;
- if (!GetAppDomain()->ToCompilationDomain()->FindImage(sFileName, MDInternalImport_NoCache, &pImage))
- {
- EEFileLoadException::Throw(sFileName, COR_E_FILENOTFOUND);
- }
-
- PEImageLayoutHolder pLayout(pImage->GetLayout(PEImageLayout::LAYOUT_FLAT,PEImage::LAYOUT_CREATEIFNEEDED));
- pRuntimeDllInfo[index].timeStamp = pLayout->GetTimeDateStamp();
- pRuntimeDllInfo[index].virtualSize = pLayout->GetVirtualSize();
-
-#else // CROSSGEN_COMPILE
-
- HMODULE hMod = CorCompileGetRuntimeDll((CorCompileRuntimeDlls)index);
-
- if (hMod == NULL)
- {
- _ASSERTE((CorCompileRuntimeDlls)index == NGEN_COMPILER_INFO);
-
- LPCWSTR wszDllName = CorCompileGetRuntimeDllName((CorCompileRuntimeDlls)index);
- if (FAILED(g_pCLRRuntime->LoadLibrary(wszDllName, &hMod)))
- {
- EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_EXECUTIONENGINE, W("Unable to load CLR DLL during ngen"));
- }
- }
-
- _ASSERTE(hMod != NULL);
-
- PEDecoder pe(hMod);
-
- pRuntimeDllInfo[index].timeStamp = pe.GetTimeDateStamp();
- pRuntimeDllInfo[index].virtualSize = pe.GetVirtualSize();
-#endif // CROSSGEN_COMPILE
-
- }
-#endif // FEATURE_CORECLR
}
//
#ifdef _TARGET_X86_
-#ifdef FEATURE_CORECLR
static CORINFO_CPU ngenCpuInfo =
{
(CPU_X86_PENTIUM_PRO << 8), // dwCPUType
// We always generate P3-compatible code on CoreCLR
*cpuInfo = ngenCpuInfo;
-#else // FEATURE_CORECLR
- static CORINFO_CPU ngenCpuInfo =
- {
- (CPU_X86_PENTIUM_4 << 8), // dwCPUType
- 0x00008001, // dwFeatures
- 0 // dwExtendedFeatures
- };
-
-#ifndef CROSSGEN_COMPILE
- GetSpecificCpuInfo(cpuInfo);
- if (!IsCompatibleCpuInfo(cpuInfo, &ngenCpuInfo))
- {
- // Use the actual cpuInfo if the platform is not compatible
- // with the "recommended" processor. We expect most platforms to be compatible
- return;
- }
-#endif
-
- *cpuInfo = ngenCpuInfo;
-#endif // FEATURE_CORECLR
#else // _TARGET_X86_
cpuInfo->dwCPUType = 0;
pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_INSTRUMENTATION_NONE;
}
-#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR)
- if (UseRyuJit())
- {
- pNativeVersionInfo->wCodegenFlags |= CORCOMPILE_CODEGEN_USE_RYUJIT;
- }
-#endif
GetTimeStampsForNativeImage(pNativeVersionInfo);
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
AssemblySpec spec;
spec.InitializeSpec(this->GetFile());
pDependencies++;
}
-#endif
return TRUE;
}
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
return TRUE;
-#else
-
- //
- // System libraries are a special case, the security info's always OK.
- //
-
- if (IsSystem())
- return TRUE;
-
-#ifdef FEATURE_NATIVE_IMAGE_GENERATION
- //
- // If we're just loading files as part of PDB generation, we're not executing code,
- // so no need to do security checks
- //
-
- if (IsNgenPDBCompilationProcess())
- return TRUE;
-#endif
-
- ETWOnStartup (SecurityCatchCall_V1, SecurityCatchCallEnd_V1);
-
-#ifdef CROSSGEN_COMPILE
- return TRUE;
-#else
-
-#ifdef FEATURE_APTCA
- if (!Security::NativeImageHasValidAptcaDependencies(pNativeImage, this))
- {
- return FALSE;
- }
-#endif // !FEATURE_APTCA
-
- GCX_COOP();
-
- BOOL fHostProtectionOK = FALSE;
- BOOL fImageAndDependenciesAreFullTrust = FALSE;
-
- EX_TRY
- {
- // Check the HostProtection settings.
- EApiCategories eRequestedProtectedCategories = GetHostProtectionManager()->GetProtectedCategories();
- if (eRequestedProtectedCategories == eNoChecks)
- fHostProtectionOK = TRUE;
-
- // Due to native code generated for one IL image being more agressively put into another
- // assembly's native image, we're disabling partial trust NGEN images. If the current
- // domain can only have fully trusted assemblies, then we can load this image, or if the current
- // assembly and its closure are all in the GAC we can also use it. Otherwise, we'll conservatively
- // disable the use of this image.
- IApplicationSecurityDescriptor *pAppDomainSecurity = this->GetAppDomain()->GetSecurityDescriptor();
- if (pAppDomainSecurity->IsFullyTrusted() && pAppDomainSecurity->IsHomogeneous())
- {
- // A fully trusted homogenous domain can only have full trust assemblies, therefore this assembly
- // and all its dependencies must be full trust
- fImageAndDependenciesAreFullTrust = TRUE;
- }
- else if (IsClosedInGAC())
- {
- // The domain allows partial trust assemblies to be loaded into it. However, this assembly and
- // all of its dependencies came from the GAC, so we know that they must all be trusted even if
- // other code in this domain is not.
- fImageAndDependenciesAreFullTrust = TRUE;
- }
- else
- {
- // The domain allows partial trust assemblies and we cannot prove that the closure of
- // dependencies of this assembly will all be fully trusted. Conservatively throw away this NGEN
- // image.
- fImageAndDependenciesAreFullTrust = FALSE;
- }
- }
- EX_CATCH
- {
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- return fHostProtectionOK && fImageAndDependenciesAreFullTrust;
-#endif // CROSSGEN_COMPILE
-
-#endif // FEATURE_CORECLR
}
#endif // FEATURE_PREJIT
-#ifdef FEATURE_CAS_POLICY
-void DomainAssembly::InitializeSecurityManager()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- GC_NOTRIGGER;
- MODE_PREEMPTIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
- GetFile()->InitializeSecurityManager();
-}
-#endif // FEATURE_CAS_POLICY
-
-#ifdef FEATURE_CAS_POLICY
-// Returns security information for the assembly based on the codebase
-void DomainAssembly::GetSecurityIdentity(SString &codebase,
- SecZone *pdwZone,
- DWORD dwFlags,
- BYTE *pbUniqueID,
- DWORD *pcbUniqueID)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pdwZone));
- PRECONDITION(CheckPointer(pbUniqueID));
- PRECONDITION(CheckPointer(pcbUniqueID));
- }
- CONTRACTL_END;
-
- GetFile()->GetSecurityIdentity(codebase, pdwZone, dwFlags, pbUniqueID, pcbUniqueID);
-}
-#endif // FEATURE_CAS_POLICY
#ifdef FEATURE_FUSION
IAssemblyBindingClosure* DomainAssembly::GetAssemblyBindingClosure(WALK_LEVEL level)
ULONG HashIdentity();
private:
-#ifdef FEATURE_CAS_POLICY
- // Pulls in URLMON's security manager. It is used to translate a codebase
- // into a zone and site
- void InitializeSecurityManager();
-#endif // FEATURE_CAS_POLICY
BOOL ShouldLoadDomainNeutral();
BOOL ShouldLoadDomainNeutralHelper();
}
CONTRACTL_END;
-#ifndef FEATURE_CORECLR
- bool success = false;
- EX_TRY
- {
- wcsncpy_s(targetParam, maxLength, AppX::GetHeadPackageMoniker(), _TRUNCATE);
- success = true;
- }
- EX_CATCH
- {
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- if (!success)
- {
- // should this ever legitimately fail??
- _ASSERTE(!"failed to get package moniker for watson");
- wcsncpy_s(targetParam, maxLength, W("missing"), _TRUNCATE);
- }
-#else
_ASSERTE(!"AppX support NYI for CoreCLR");
-#endif // FEATURE_CORECLR
}
void BaseBucketParamsManager::GetPRAID(__out_ecount(maxLength) WCHAR* targetParam, int maxLength)
}
CONTRACTL_END;
-#ifndef FEATURE_CORECLR
- LPCWSTR pPraid = NULL;
- if (SUCCEEDED(AppX::GetApplicationId(pPraid)))
- {
- _snwprintf_s(targetParam,
- maxLength,
- _TRUNCATE,
- W("praid:%s"),
- pPraid);
- }
- else
- {
- // should this ever legitimately fail??
- _ASSERTE(!"failed to get PRAID for watson");
- wcsncpy_s(targetParam, maxLength, W("missing"), _TRUNCATE);
- }
-#else
_ASSERTE(!"PRAID support NYI for CoreCLR");
-#endif
}
void BaseBucketParamsManager::GetIlRva(__out_ecount(maxLength) WCHAR* targetParam, int maxLength)
}
CONTRACTL_END;
-#if defined(FEATURE_APPX) && !defined(FEATURE_CORECLR)
- if (AppX::IsAppXProcess() && !AppX::IsAppXNGen())
- return MoCrash;
- else
-#endif // FEATURE_APPX
#ifdef FEATURE_WINDOWSPHONE
return WinPhoneCrash;
{
- #if !defined(FEATURE_CORECLR)
- // Use the version of DW20.exe that lives in the system directory.
- DWORD ret;
-
- if (FAILED(GetCORSystemDirectoryInternaL(watsonAppName)))
- {
- hr = E_FAIL;
- break;
- }
- watsonCommandLine.Set(watsonAppName);
- watsonCommandLine.Append(kWatsonImageNameOnVista);
-
- #else // FEATURE_CORECLR
HKEYHolder hKey;
// Look for key \\HKLM\Software\Microsoft\PCHealth\ErrorReporting\DW\Installed"
DWORD ret = WszRegOpenKeyEx(HKEY_LOCAL_MACHINE,
ClrRegReadString(hKey, kWatsonValue, watsonAppName);
- #endif // ! FEATURE_CORECLR
COUNT_T len = watsonCommandLine.GetCount();
WCHAR* buffer = watsonCommandLine.OpenUnicodeBuffer(len);
}
WatsonBucketType bucketType = GetWatsonBucketType();
-#ifndef FEATURE_CORECLR
- if (bucketType == MoCrash)
- {
- MoCrashBucketParamsManager moCrashManager(pGenericModeBlock, tore, currentPC, pThread, pThrowable);
- moCrashManager.PopulateBucketParameters();
- }
- else
-#endif // !FEATURE_CORECLR
{
#ifdef FEATURE_WINDOWSPHONE
_ASSERTE(bucketType == WinPhoneCrash);
#if defined(PRESERVE_WATSON_ACROSS_CONTEXTS)
GenericModeBlock *pBuckets = NULL;
-#ifdef FEATURE_CORECLR
// On CoreCLR, Watson may not be enabled. Thus, we should
// skip this.
if (IsWatsonEnabled())
-#endif // FEATURE_CORECLR
{
if (pThread != NULL)
{
Thread *pThread = GetThread();
-#ifdef FEATURE_CORECLR
// If watson isn't available (eg. in Silverlight), then use a simple dialog box instead
if (!IsWatsonEnabled())
{
return fri.m_faultReportResult;
}
-#endif // FEATURE_CORECLR
#ifdef FEATURE_UEF_CHAINMANAGER
if (g_pUEFManager && !tore.IsUserBreakpoint())
class MethodDesc;
-#ifndef FEATURE_CORECLR
-// Every program tends to use only a subset of ~1000 FCalls. Even big apps like
-// VS do not usually hit more than 300. Pick a size of the hashtable that's sufficient
-// for the typical case. It is ok to have some colisions in the rare case. Note that
-// the size of the table should be prime.
-#define FCALL_HASH_SIZE 257
-#else
// CoreCLR defines fewer FCalls so make the hashtable even smaller.
#define FCALL_HASH_SIZE 127
-#endif
typedef DPTR(struct ECHash) PTR_ECHash;
FCFuncElement("nSetSecondary", DependentHandle::nSetSecondary)
FCFuncEnd()
-#ifndef FEATURE_CORECLR
-FCFuncStart(gSizedRefHandleFuncs)
- FCFuncElement("CreateSizedRef", SizedRefHandle::Initialize)
- FCFuncElement("FreeSizedRef", SizedRefHandle::Free)
- FCFuncElement("GetTargetOfSizedRef", SizedRefHandle::GetTarget)
- FCFuncElement("GetApproximateSizeOfSizedRef", SizedRefHandle::GetApproximateSize)
-FCFuncEnd()
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_RWLOCK
FCFuncStart(gRWLockFuncs)
FCFuncEnd()
#endif
-#ifdef FEATURE_CORECLR
FCFuncStart(gSymWrapperCodePunkSafeHandleFuncs)
FCFuncElement("nGetDReleaseTarget", COMPunkSafeHandle::nGetDReleaseTarget)
FCFuncEnd()
-#endif //FEATURE_CORECLR
FCFuncStart(gParseNumbersFuncs)
FCFuncElement("IntToString", ParseNumbers::IntToString)
FCFuncElement("StringToLong", ParseNumbers::StringToLong)
FCFuncEnd()
-#ifndef FEATURE_CORECLR // FCalls used by System.TimeSpan
-FCFuncStart(gTimeSpanFuncs)
- FCFuncElement("LegacyFormatMode", SystemNative::LegacyFormatMode)
-FCFuncEnd()
-#endif // !FEATURE_CORECLR
FCFuncStart(gObjectFuncs)
FCIntrinsic("GetType", ObjectNative::GetClass, CORINFO_INTRINSIC_Object_GetType)
FCFuncStart(gDateTimeFuncs)
FCFuncElement("GetSystemTimeAsFileTime", SystemNative::__GetSystemTimeAsFileTime)
-#ifndef FEATURE_CORECLR
- QCFuncElement("LegacyParseMode", SystemNative::LegacyDateTimeParseMode)
- QCFuncElement("EnableAmPmParseAdjustment", SystemNative::EnableAmPmParseAdjustment)
-#endif
FCFuncEnd()
FCFuncStart(gEnvironmentFuncs)
FCFuncElement("get_ExitCode", SystemNative::GetExitCode)
FCFuncElement("get_HasShutdownStarted", SystemNative::HasShutdownStarted)
QCFuncElement("GetProcessorCount", SystemNative::GetProcessorCount)
-#ifndef FEATURE_CORECLR
- FCFuncElement("nativeGetEnvironmentVariable", SystemNative::_GetEnvironmentVariable)
- FCFuncElement("GetCompatibilityFlag", SystemNative::_GetCompatibilityFlag)
- QCFuncElement("GetCommandLine", SystemNative::_GetCommandLine)
- FCFuncElement("GetResourceFromDefault", GetResourceFromDefault)
-#endif // !FEATURE_CORECLR
FCFuncElement("GetCommandLineArgsNative", SystemNative::GetCommandLineArgs)
FCFuncElement("get_CurrentProcessorNumber", SystemNative::GetCurrentProcessorNumber)
#endif // FEATURE_COMINTEROP
FCFuncElementSig("FailFast", &gsig_SM_Str_RetVoid, SystemNative::FailFast)
FCFuncElementSig("FailFast", &gsig_SM_Str_Exception_RetVoid, SystemNative::FailFastWithException)
-#ifndef FEATURE_CORECLR
- QCFuncElement("GetIsCLRHosted", SystemNative::IsCLRHosted)
- QCFuncElement("TriggerCodeContractFailure", SystemNative::TriggerCodeContractFailure)
-#endif // !FEATURE_CORECLR
FCFuncEnd()
FCFuncStart(gRuntimeEnvironmentFuncs)
FCFuncElement("GetModuleFileName", SystemNative::_GetModuleFileName)
-#ifndef FEATURE_CORECLR
- QCFuncElement("_GetSystemVersion", SystemNative::_GetSystemVersion)
-#endif
FCFuncEnd()
FCFuncStart(gSerializationFuncs)
-#ifndef FEATURE_CORECLR
- FCFuncElement("GetEnableUnsafeTypeForwarders", ReflectionSerialization::GetEnableUnsafeTypeForwarders)
- FCFuncElement("nativeGetSafeUninitializedObject", ReflectionSerialization::GetSafeUninitializedObject)
-#endif
FCFuncElement("nativeGetUninitializedObject", ReflectionSerialization::GetUninitializedObject)
FCFuncEnd()
FCFuncElement("IsImmutableAgileException", ExceptionNative::IsImmutableAgileException)
FCFuncElement("nIsTransient", ExceptionNative::IsTransient)
FCFuncElement("GetMethodFromStackTrace", SystemNative::GetMethodFromStackTrace)
-#ifndef FEATURE_CORECLR
- FCFuncElement("StripFileInfo", ExceptionNative::StripFileInfo)
-#endif
QCFuncElement("GetMessageFromNativeResources", ExceptionNative::GetMessageFromNativeResources)
#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
FCFuncElement("PrepareForForeignExceptionRaise", ExceptionNative::PrepareForForeignExceptionRaise)
FCFuncElement("Allocate", RuntimeTypeHandle::Allocate) //for A.CI
FCFuncElement("CompareCanonicalHandles", RuntimeTypeHandle::CompareCanonicalHandles)
FCIntrinsic("GetValueInternal", RuntimeTypeHandle::GetValueInternal, CORINFO_INTRINSIC_RTH_GetValueInternal)
-#ifndef FEATURE_CORECLR
- FCFuncElement("IsEquivalentTo", RuntimeTypeHandle::IsEquivalentTo)
- FCFuncElement("IsEquivalentType", RuntimeTypeHandle::IsEquivalentType)
-#endif // FEATURE_CORECLR
FCFuncEnd()
FCFuncStart(gMetaDataImport)
FCFuncElement("GetMethodFromCanonical", RuntimeMethodHandle::GetMethodFromCanonical)
FCFuncElement("IsDynamicMethod", RuntimeMethodHandle::IsDynamicMethod)
FCFuncElement("GetMethodBody", RuntimeMethodHandle::GetMethodBody)
-#ifndef FEATURE_CORECLR
- FCFuncElement("_IsTokenSecurityTransparent", RuntimeMethodHandle::IsTokenSecurityTransparent)
- QCFuncElement("_IsSecurityCritical", RuntimeMethodHandle::IsSecurityCritical)
- QCFuncElement("_IsSecuritySafeCritical", RuntimeMethodHandle::IsSecuritySafeCritical)
-#endif // FEATURE_CORECLR
QCFuncElement("_IsSecurityTransparent", RuntimeMethodHandle::IsSecurityTransparent)
FCFuncElement("CheckLinktimeDemands", RuntimeMethodHandle::CheckLinktimeDemands)
QCFuncElement("IsCAVisibleFromDecoratedType", RuntimeMethodHandle::IsCAVisibleFromDecoratedType)
FCFuncElement("GetResolver", RuntimeMethodHandle::GetResolver)
FCFuncElement("GetLoaderAllocator", RuntimeMethodHandle::GetLoaderAllocator)
FCFuncElement("GetSpecialSecurityFlags", ReflectionInvocation::GetSpecialSecurityFlags)
-#ifndef FEATURE_CORECLR
- QCFuncElement("GetCallerType", RuntimeMethodHandle::GetCallerType)
- FCFuncElement("PerformSecurityCheck", ReflectionInvocation::PerformSecurityCheck)
-#endif // FEATURE_CORECLR
FCFuncEnd()
FCFuncStart(gCOMDefaultBinderFuncs)
QCFuncElement("ResolveMethod", ModuleHandle::ResolveMethod)
QCFuncElement("_ContainsPropertyMatchingHash", ModuleHandle::ContainsPropertyMatchingHash)
QCFuncElement("ResolveField", ModuleHandle::ResolveField)
-#ifndef FEATURE_CORECLR
- QCFuncElement("GetAssembly", ModuleHandle::GetAssembly)
-#endif // FEATURE_CORECLR
QCFuncElement("GetPEKind", ModuleHandle::GetPEKind)
FCFuncElement("GetMDStreamVersion", ModuleHandle::GetMDStreamVersion)
FCFuncEnd()
QCFuncElement("SetParamInfo", COMDynamicWrite::SetParamInfo)
QCFuncElement("SetConstantValue", COMDynamicWrite::SetConstantValue)
QCFuncElement("DefineCustomAttribute", COMDynamicWrite::DefineCustomAttribute)
-#ifndef FEATURE_CORECLR
- QCFuncElement("AddDeclarativeSecurity", COMDynamicWrite::AddDeclarativeSecurity)
-#endif // FEATURE_CORECLR
FCFuncEnd()
#ifdef FEATURE_METHOD_RENTAL
FCFuncEnd()
#endif // FEATURE_FUSION
-#ifndef FEATURE_CORECLR
-FCFuncStart(gWindowsRuntimeContextFuncs)
- QCFuncElement("CreateDesignerContext", AppDomainNative::CreateDesignerContext)
- QCFuncElement("SetCurrentContext", AppDomainNative::SetCurrentDesignerContext)
-FCFuncEnd()
-#endif // FEATURE_CORECLR
FCFuncStart(gAppDomainFuncs)
#ifdef FEATURE_REMOTING
QCFuncElement("GetAppDomainManagerType", AppDomainNative::GetAppDomainManagerType)
QCFuncElement("SetAppDomainManagerType", AppDomainNative::SetAppDomainManagerType)
FCFuncElement("nGetFriendlyName", AppDomainNative::GetFriendlyName)
-#ifndef FEATURE_CORECLR
- FCFuncElement("GetSecurityDescriptor", AppDomainNative::GetSecurityDescriptor)
- FCFuncElement("nIsDefaultAppDomainForEvidence", AppDomainNative::IsDefaultAppDomainForEvidence)
- FCFuncElement("nGetAssemblies", AppDomainNative::GetAssemblies)
-#endif
-#ifdef FEATURE_APTCA
- QCFuncElement("SetCanonicalConditionalAptcaList", AppDomainNative::SetCanonicalConditionalAptcaList)
-#endif // FEATURE_ATPCA
QCFuncElement("SetSecurityHomogeneousFlag", AppDomainNative::SetSecurityHomogeneousFlag)
QCFuncElement("SetupDomainSecurity", AppDomainNative::SetupDomainSecurity)
FCFuncElement("nSetupFriendlyName", AppDomainNative::SetupFriendlyName)
FCFuncElement("IsDomainIdValid", AppDomainNative::IsDomainIdValid)
FCFuncElement("nApplyPolicy", AppDomainNative::nApplyPolicy)
#endif // FEATURE_REMOTING
-#ifdef FEATURE_CORECLR
QCFuncElement("nSetupBindingPaths", AppDomainNative::SetupBindingPaths)
QCFuncElement("nSetNativeDllSearchDirectories", AppDomainNative::SetNativeDllSearchDirectories)
-#endif
FCFuncElement("IsFinalizingForUnload", AppDomainNative::IsFinalizingForUnload)
FCFuncElement("PublishAnonymouslyHostedDynamicMethodsAssembly", AppDomainNative::PublishAnonymouslyHostedDynamicMethodsAssembly)
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
#endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING
FCFuncEnd()
-#if defined(FEATURE_MULTICOREJIT) && !defined(FEATURE_CORECLR)
-FCFuncStart(gProfileOptimizationFuncs)
- QCFuncElement("InternalSetProfileRoot", MultiCoreJITNative::InternalSetProfileRoot)
- QCFuncElement("InternalStartProfile", MultiCoreJITNative::InternalStartProfile)
-FCFuncEnd()
-#endif // defined(FEATURE_MULTICOREJIT) && !defined(FEATURE_CORECLR)
FCFuncStart(gUtf8String)
FCFuncElement("EqualsCaseSensitive", Utf8String::EqualsCaseSensitive)
QCFuncElement("GetHashAlgorithm", AssemblyNative::GetHashAlgorithm)
QCFuncElement("GetLocale", AssemblyNative::GetLocale)
QCFuncElement("GetPublicKey", AssemblyNative::GetPublicKey)
-#ifndef FEATURE_CORECLR
- QCFuncElement("GetSecurityRuleSet", AssemblyNative::GetSecurityRuleSet)
-#endif // !FEATURE_CORECLR
QCFuncElement("GetSimpleName", AssemblyNative::GetSimpleName)
QCFuncElement("GetVersion", AssemblyNative::GetVersion)
FCFuncElement("FCallIsDynamic", AssemblyNative::IsDynamic)
FCFuncElement("_nLoad", AssemblyNative::Load)
-#ifndef FEATURE_CORECLR
- FCFuncElement("IsFrameworkAssembly", AssemblyNative::IsFrameworkAssembly)
- FCFuncElement("IsNewPortableAssembly", AssemblyNative::IsNewPortableAssembly)
-#endif
FCFuncElement("nLoadImage", AssemblyNative::LoadImage)
-#ifndef FEATURE_CORECLR
- QCFuncElement("LoadModule", AssemblyNative::LoadModule)
-#endif // FEATURE_CORECLR
QCFuncElement("GetType", AssemblyNative::GetType)
QCFuncElement("GetManifestResourceInfo", AssemblyNative::GetManifestResourceInfo)
-#ifndef FEATURE_CORECLR
- QCFuncElement("UseRelativeBindForSatellites", AssemblyNative::UseRelativeBindForSatellites)
-#endif
QCFuncElement("GetModules", AssemblyNative::GetModules)
QCFuncElement("GetModule", AssemblyNative::GetModule)
FCFuncElement("GetReferencedAssemblies", AssemblyNative::GetReferencedAssemblies)
QCFuncElement("GetEntryPoint", AssemblyNative::GetEntryPoint)
QCFuncElement("IsAllSecurityTransparent", AssemblyNative::IsAllSecurityTransparent)
QCFuncElement("IsAllSecurityCritical", AssemblyNative::IsAllSecurityCritical)
-#ifndef FEATURE_CORECLR
- QCFuncElement("IsAllSecuritySafeCritical", AssemblyNative::IsAllSecuritySafeCritical)
- QCFuncElement("IsAllPublicAreaSecuritySafeCritical", AssemblyNative::IsAllPublicAreaSecuritySafeCritical)
- QCFuncElement("GetGrantSet", AssemblyNative::GetGrantSet)
-#endif // !FEATURE_CORECLR
QCFuncElement("GetImageRuntimeVersion", AssemblyNative::GetImageRuntimeVersion)
FCFuncElement("IsReflectionOnly", AssemblyNative::IsReflectionOnly)
FCFuncElement("GetManifestModule", AssemblyHandle::GetManifestModule)
FCFuncElement("GetToken", AssemblyHandle::GetToken)
-#ifdef FEATURE_APTCA
- FCFuncElement("AptcaCheck", AssemblyHandle::AptcaCheck)
-#endif // FEATURE_APTCA
FCFuncEnd()
-#ifdef FEATURE_CORECLR
FCFuncStart(gAssemblyExtensionsFuncs)
QCFuncElement("InternalTryGetRawMetadata", AssemblyNative::InternalTryGetRawMetadata)
FCFuncEnd()
-#endif
#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
FCFuncStart(gAssemblyLoadContextFuncs)
FCFuncElement("nInit", AssemblyNameNative::Init)
FCFuncElement("nToString", AssemblyNameNative::ToString)
FCFuncElement("nGetPublicKeyToken", AssemblyNameNative::GetPublicKeyToken)
-#ifndef FEATURE_CORECLR
- FCFuncElement("EscapeCodeBase", AssemblyNameNative::EscapeCodeBase)
-#endif // !FEATURE_CORECLR
FCFuncElement("ReferenceMatchesDefinitionInternal", AssemblyNameNative::ReferenceMatchesDefinition)
FCFuncElement("nGetFileInformation", AssemblyNameNative::GetFileInformation)
FCFuncEnd()
FCFuncStart(gAssemblyBuilderFuncs)
FCFuncElement("nCreateDynamicAssembly", AppDomainNative::CreateDynamicAssembly)
FCFuncElement("GetInMemoryAssemblyModule", AssemblyNative::GetInMemoryAssemblyModule)
-#ifndef FEATURE_CORECLR
- FCFuncElement("GetOnDiskAssemblyModule", AssemblyNative::GetOnDiskAssemblyModule)
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- QCFuncElement("DefineDynamicModule", COMModule::DefineDynamicModule)
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
- QCFuncElement("PrepareForSavingManifestToDisk", AssemblyNative::PrepareForSavingManifestToDisk)
- QCFuncElement("SaveManifestToDisk", AssemblyNative::SaveManifestToDisk)
- QCFuncElement("AddFile", AssemblyNative::AddFile)
- QCFuncElement("SetFileHashValue", AssemblyNative::SetFileHashValue)
- QCFuncElement("AddStandAloneResource", AssemblyNative::AddStandAloneResource)
- QCFuncElement("AddExportedTypeOnDisk", AssemblyNative::AddExportedTypeOnDisk)
- QCFuncElement("AddExportedTypeInMemory", AssemblyNative::AddExportedTypeInMemory)
- QCFuncElement("AddDeclarativeSecurity", AssemblyNative::AddDeclarativeSecurity)
- QCFuncElement("CreateVersionInfoResource", AssemblyNative::CreateVersionInfoResource)
-#endif // !FEATURE_CORECLR
FCFuncEnd()
#ifdef MDA_SUPPORTED
FCFuncStart(gThreadFuncs)
FCDynamic("InternalGetCurrentThread", CORINFO_INTRINSIC_Illegal, ECall::InternalGetCurrentThread)
FCFuncElement("StartInternal", ThreadNative::Start)
-#ifndef FEATURE_CORECLR
- FCFuncElement("SuspendInternal", ThreadNative::Suspend)
- FCFuncElement("ResumeInternal", ThreadNative::Resume)
-#endif
#ifdef FEATURE_LEAK_CULTURE_INFO
FCFuncElement("nativeGetSafeCulture", ThreadNative::nativeGetSafeCulture)
#else
FCFuncElement("InternalCrossContextCallback", ThreadNative::InternalCrossContextCallback)
#endif
QCFuncElement("InformThreadNameChange", ThreadNative::InformThreadNameChange)
-#ifndef FEATURE_CORECLR
- QCFuncElement("GetProcessDefaultStackSize", ThreadNative::GetProcessDefaultStackSize)
- FCFuncElement("BeginCriticalRegion", ThreadNative::BeginCriticalRegion)
- FCFuncElement("EndCriticalRegion", ThreadNative::EndCriticalRegion)
- FCFuncElement("BeginThreadAffinity", ThreadNative::BeginThreadAffinity)
- FCFuncElement("EndThreadAffinity", ThreadNative::EndThreadAffinity)
-#endif // FEATURE_CORECLR
-#ifndef FEATURE_CORECLR
- FCFuncElement("ResetAbortNative", ThreadNative::ResetAbort)
-#endif // FEATURE_CORECLR
FCFuncElement("SpinWaitInternal", ThreadNative::SpinWait)
QCFuncElement("YieldInternal", ThreadNative::YieldThread)
FCIntrinsic("GetCurrentThreadNative", ThreadNative::GetCurrentThread, CORINFO_INTRINSIC_GetCurrentManagedThread)
FCFuncElement("StartupSetApartmentStateInternal", ThreadNative::StartupSetApartmentState)
#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
FCIntrinsic("MemoryBarrier", ThreadNative::FCMemoryBarrier, CORINFO_INTRINSIC_MemoryBarrier)
-#ifndef FEATURE_CORECLR // coreclr does not support abort reason
- FCFuncElement("SetAbortReason", ThreadNative::SetAbortReason)
- FCFuncElement("GetAbortReason", ThreadNative::GetAbortReason)
- FCFuncElement("ClearAbortReason", ThreadNative::ClearAbortReason)
-#endif
FCFuncEnd()
FCFuncStart(gThreadPoolFuncs)
FCFuncElement("FormatInt64", COMNumber::FormatInt64)
FCFuncElement("FormatUInt64", COMNumber::FormatUInt64)
FCFuncElement("FormatSingle", COMNumber::FormatSingle)
-#if !defined(FEATURE_CORECLR)
- FCFuncElement("FormatNumberBuffer", COMNumber::FormatNumberBuffer)
-#endif // !FEATURE_CORECLR
FCFuncElement("NumberBufferToDecimal", COMNumber::NumberBufferToDecimal)
FCFuncElement("NumberBufferToDouble", COMNumber::NumberBufferToDouble)
FCFuncEnd()
FCFuncElement("FCallToDecimal", COMCurrency::DoToDecimal)
FCFuncEnd()
-#ifndef FEATURE_CORECLR
-FCFuncStart(gCLRConfigFuncs)
- FCFuncElement("CheckLegacyManagedDeflateStream", SystemNative::CheckLegacyManagedDeflateStream)
- FCFuncElement("CheckThrowUnobservedTaskExceptions", SystemNative::CheckThrowUnobservedTaskExceptions)
-FCFuncEnd()
-#endif // ifndef FEATURE_CORECLR
#if !defined(FEATURE_COREFX_GLOBALIZATION)
FCFuncStart(gCompareInfoFuncs)
QCFuncElement("NativeInternalInitSortHandle", COMNlsInfo::InternalInitSortHandle)
QCFuncElement("InternalIsSortable", COMNlsInfo::InternalIsSortable)
QCFuncElement("InternalGetSortKey", COMNlsInfo::InternalGetSortKey)
-#ifndef FEATURE_CORECLR
- QCFuncElement("InternalGetSortVersion", COMNlsInfo::InternalGetSortVersion)
-#endif
QCFuncElement("InternalGetNlsVersionEx", COMNlsInfo::InternalGetNlsVersionEx)
FCFuncEnd()
QCFuncElement("InternalGetUserDefaultUILanguage", COMNlsInfo::InternalGetUserDefaultUILanguage)
QCFuncElement("InternalGetSystemDefaultUILanguage", COMNlsInfo::InternalGetSystemDefaultUILanguage)
// Added but disabled from desktop in .NET 4.0, stayed disabled in .NET 4.5
-#ifdef FEATURE_CORECLR
FCFuncElement("nativeGetResourceFallbackArray", COMNlsInfo::nativeGetResourceFallbackArray)
-#endif
FCFuncEnd()
FCFuncStart(gTextInfoFuncs)
FCFuncElement("UnsafeAddrOfPinnedArrayElement", MarshalNative::FCUnsafeAddrOfPinnedArrayElement)
FCFuncElement("GetExceptionCode", ExceptionNative::GetExceptionCode)
QCFuncElement("GetHINSTANCE", COMModule::GetHINSTANCE)
-#ifndef FEATURE_CORECLR
- QCFuncElement("InternalNumParamBytes", MarshalNative::NumParamBytes)
- FCFuncElement("GetExceptionPointers", ExceptionNative::GetExceptionPointers)
- FCFuncElement("GetUnmanagedThunkForManagedMethodPtr", MarshalNative::GetUnmanagedThunkForManagedMethodPtr)
- FCFuncElement("GetManagedThunkForUnmanagedMethodPtr", MarshalNative::GetManagedThunkForUnmanagedMethodPtr)
- FCFuncElement("InternalGetThreadFromFiberCookie", MarshalNative::GetThreadFromFiberCookie)
-#endif
FCFuncElement("OffsetOfHelper", MarshalNative::OffsetOfHelper)
FCFuncElement("SizeOfType", SafeBuffer::SizeOfType)
FCFuncElement("GetNativeActivationFactory", MarshalNative::GetNativeActivationFactory)
FCFuncElement("GetIUnknownForObjectNative", MarshalNative::GetIUnknownForObjectNative)
-#ifndef FEATURE_CORECLR
- FCFuncElement("GetIDispatchForObjectNative", MarshalNative::GetIDispatchForObjectNative)
-#endif // FEATURE_CORECLR
FCFuncElement("GetComInterfaceForObjectNative", MarshalNative::GetComInterfaceForObjectNative)
FCFuncElement("InternalReleaseComObject", MarshalNative::ReleaseComObject)
FCFuncElement("Release", MarshalNative::Release)
FCFuncElement("GetTypedObjectForIUnknown", MarshalNative::GetTypedObjectForIUnknown)
FCFuncElement("ChangeWrapperHandleStrength", MarshalNative::ChangeWrapperHandleStrength)
FCFuncElement("CleanupUnusedObjectsInCurrentContext", MarshalNative::CleanupUnusedObjectsInCurrentContext)
-#ifndef FEATURE_CORECLR
- FCFuncElement("GetLoadedTypeForGUID", MarshalNative::GetLoadedTypeForGUID)
- FCFuncElement("GetITypeInfoForType", MarshalNative::GetITypeInfoForType)
- FCFuncElement("IsTypeVisibleFromCom", MarshalNative::IsTypeVisibleFromCom)
- FCFuncElement("FCallGenerateGuidForType", MarshalNative::DoGenerateGuidForType)
- FCFuncElement("FCallGetTypeLibGuid", MarshalNative::DoGetTypeLibGuid)
- FCFuncElement("GetTypeLibLcid", MarshalNative::GetTypeLibLcid)
- FCFuncElement("GetTypeLibVersion", MarshalNative::GetTypeLibVersion)
- FCFuncElement("FCallGetTypeInfoGuid", MarshalNative::DoGetTypeInfoGuid)
- FCFuncElement("FCallGetTypeLibGuidForAssembly", MarshalNative::DoGetTypeLibGuidForAssembly)
- FCFuncElement("_GetTypeLibVersionForAssembly", MarshalNative::GetTypeLibVersionForAssembly)
- FCFuncElement("GetEndComSlot", MarshalNative::GetEndComSlot)
- FCFuncElement("GetMethodInfoForComSlot", MarshalNative::GetMethodInfoForComSlot)
- FCFuncElement("InternalGetComSlotForMethodInfo", MarshalNative::GetComSlotForMethodInfo)
- FCFuncElement("InternalSwitchCCW", MarshalNative::SwitchCCW)
- FCFuncElement("InternalWrapIUnknownWithComObject", MarshalNative::WrapIUnknownWithComObject)
- QCFuncElement("_GetInspectableIids", MarshalNative::GetInspectableIIDs)
- QCFuncElement("_GetCachedWinRTTypes", MarshalNative::GetCachedWinRTTypes)
- QCFuncElement("_GetCachedWinRTTypeByIid", MarshalNative::GetCachedWinRTTypeByIID)
-#endif // FEATURE_CORECLR
#endif // FEATURE_COMINTEROP
FCFuncEnd()
#ifdef FEATURE_COMINTEROP
-#ifndef FEATURE_CORECLR
-FCFuncStart(gExtensibleClassFactoryFuncs)
- FCFuncElement("RegisterObjectCreationCallback", RegisterObjectCreationCallback)
-FCFuncEnd()
-#endif
#ifdef FEATURE_COMINTEROP_TLB_SUPPORT
FCIntrinsic("InitializeArray", ArrayNative::InitializeArray, CORINFO_INTRINSIC_InitializeArray)
FCFuncElement("_RunClassConstructor", ReflectionInvocation::RunClassConstructor)
FCFuncElement("_RunModuleConstructor", ReflectionInvocation::RunModuleConstructor)
-#ifndef FEATURE_CORECLR
- FCFuncElement("_PrepareMethod", ReflectionInvocation::PrepareMethod)
-#endif // !FEATURE_CORECLR
QCFuncElement("_CompileMethod", ReflectionInvocation::CompileMethod)
-#ifndef FEATURE_CORECLR
- FCFuncElement("PrepareDelegate", ReflectionInvocation::PrepareDelegate)
-#endif // !FEATURE_CORECLR
FCFuncElement("PrepareContractedDelegate", ReflectionInvocation::PrepareContractedDelegate)
FCFuncElement("ProbeForSufficientStack", ReflectionInvocation::ProbeForSufficientStack)
FCFuncElement("ExecuteCodeWithGuaranteedCleanup", ReflectionInvocation::ExecuteCodeWithGuaranteedCleanup)
FCFuncEnd()
FCFuncStart(gStubHelperFuncs)
-#ifndef FEATURE_CORECLR
-#ifndef _WIN64
- FCFuncElement("GetFinalStubTarget", StubHelpers::GetFinalStubTarget)
-#endif // !_WIN64
- FCFuncElement("DemandPermission", StubHelpers::DemandPermission)
-#endif // !FEATURE_CORECLR
FCFuncElement("IsQCall", StubHelpers::IsQCall)
FCFuncElement("InitDeclaringType", StubHelpers::InitDeclaringType)
FCIntrinsic("GetNDirectTarget", StubHelpers::GetNDirectTarget, CORINFO_INTRINSIC_StubHelpers_GetNDirectTarget)
FCFuncElement("GetDelegateTarget", StubHelpers::GetDelegateTarget)
FCFuncElement("SetLastError", StubHelpers::SetLastError)
-#ifdef FEATURE_CORECLR
FCFuncElement("ClearLastError", StubHelpers::ClearLastError)
-#endif
FCFuncElement("ThrowInteropParamException", StubHelpers::ThrowInteropParamException)
FCFuncElement("InternalGetHRExceptionObject", StubHelpers::GetHRExceptionObject)
#ifdef FEATURE_COMINTEROP
FCFuncElement("InternalCheckDomain", MarshalNative::GCHandleInternalCheckDomain)
FCFuncEnd()
-#ifndef FEATURE_CORECLR
-FCFuncStart(gConsoleFuncs)
- QCFuncElement("GetTitleNative", ConsoleNative::GetTitle)
-FCFuncEnd()
-#endif // ifndef FEATURE_CORECLR
FCFuncStart(gVersioningHelperFuncs)
FCFuncElement("GetRuntimeId", GetRuntimeId_Wrapper)
FCClassElement("ArrayWithOffset", "System.Runtime.InteropServices", gArrayWithOffsetFuncs)
FCClassElement("AssemblyBuilder", "System.Reflection.Emit", gAssemblyBuilderFuncs)
-#ifdef FEATURE_CORECLR
FCClassElement("AssemblyExtensions", "System.Reflection.Metadata", gAssemblyExtensionsFuncs)
-#endif
#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
FCClassElement("AssemblyLoadContext", "System.Runtime.Loader", gAssemblyLoadContextFuncs)
FCClassElement("Assert", "System.Diagnostics", gDiagnosticsAssert)
FCClassElement("BCLDebug", "System", gBCLDebugFuncs)
FCClassElement("Buffer", "System", gBufferFuncs)
-#ifndef FEATURE_CORECLR
-// Since the 2nd letter of the classname is capital, we need to sort this before all class names
-// that start with Cx where x is any small letter (strcmp is used for verification).
-FCClassElement("CLRConfig", "System", gCLRConfigFuncs)
-#endif // FEATURE_CORECLR
#if !defined(FEATURE_COREFX_GLOBALIZATION)
FCClassElement("CalendarData", "System.Globalization", gCalendarDataFuncs)
#endif // !defined(FEATURE_COREFX_GLOBALIZATION)
-#ifndef FEATURE_CORECLR
-FCClassElement("ChannelServices", "System.Runtime.Remoting.Channels", gChannelServicesFuncs)
-#endif // FEATURE_CORECLR
FCClassElement("CompareInfo", "System.Globalization", gCompareInfoFuncs)
FCClassElement("CompatibilitySwitch", "System.Runtime.Versioning", gCompatibilitySwitchFuncs)
-#ifndef FEATURE_CORECLR
-FCClassElement("Console", "System", gConsoleFuncs)
-#endif // ifndef FEATURE_CORECLR
#ifdef FEATURE_REMOTING
FCClassElement("Context", "System.Runtime.Remoting.Contexts", gContextFuncs)
#endif
FCClassElement("EventArgsMarshaler", "System.StubHelpers", gEventArgsMarshalerFuncs)
#endif // FEATURE_COMINTEROP
FCClassElement("Exception", "System", gExceptionFuncs)
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
-FCClassElement("ExtensibleClassFactory", "System.Runtime.InteropServices", gExtensibleClassFactoryFuncs)
-#endif
FCClassElement("FileLoadException", "System.IO", gFileLoadExceptionFuncs)
FCClassElement("FormatterServices", "System.Runtime.Serialization", gSerializationFuncs)
FCClassElement("GC", "System", gGCInterfaceFuncs)
#endif
FCClassElement("OverlappedData", "System.Threading", gOverlappedFuncs)
FCClassElement("ParseNumbers", "System", gParseNumbersFuncs)
-#ifndef FEATURE_CORECLR
-FCClassElement("PasswordDeriveBytes", "System.Security.Cryptography", gPasswordDeriveBytesFuncs)
-#endif
-#if defined(FEATURE_MULTICOREJIT) && !defined(FEATURE_CORECLR)
-FCClassElement("ProfileOptimization", "System.Runtime", gProfileOptimizationFuncs)
-#endif // defined(FEATURE_MULTICOREJIT) && !defined(FEATURE_CORECLR)
-#ifdef FEATURE_CORECLR
FCClassElement("PunkSafeHandle", "System.Reflection.Emit", gSymWrapperCodePunkSafeHandleFuncs)
-#endif
-#ifndef FEATURE_CORECLR
-FCClassElement("RNGCryptoServiceProvider", "System.Security.Cryptography", gRNGCryptoServiceProviderFuncs)
-#endif
#ifdef FEATURE_RWLOCK
FCClassElement("ReaderWriterLock", "System.Threading", gRWLockFuncs)
#endif // FEATURE_RWLOCK
FCClassElement("SafeTypeNameParserHandle", "System", gSafeTypeNameParserHandle)
FCClassElement("Signature", "System", gSignatureNative)
-#ifndef FEATURE_CORECLR
-FCClassElement("SizedReference", "System", gSizedRefHandleFuncs)
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_REMOTING
FCClassElement("StackBuilderSink", "System.Runtime.Remoting.Messaging", gStackBuilderSinkFuncs)
#endif
#endif // !defined(FEATURE_COREFX_GLOBALIZATION)
FCClassElement("Thread", "System.Threading", gThreadFuncs)
FCClassElement("ThreadPool", "System.Threading", gThreadPoolFuncs)
-#ifndef FEATURE_CORECLR
-FCClassElement("TimeSpan", "System", gTimeSpanFuncs)
-#endif // !FEATURE_CORECLR
FCClassElement("TimerQueue", "System.Threading", gTimerFuncs)
FCClassElement("Type", "System", gSystem_Type)
FCClassElement("TypeBuilder", "System.Reflection.Emit", gCOMClassWriter)
FCClassElement("WindowsRuntimeBufferHelper", "System.Runtime.InteropServices.WindowsRuntime", gWindowsRuntimeBufferHelperFuncs)
#endif
-#ifndef FEATURE_CORECLR
-FCClassElement("WindowsRuntimeDesignerContext", "System.Runtime.DesignerServices", gWindowsRuntimeContextFuncs)
-#endif
#if defined(FEATURE_COMINTEROP) && defined(FEATURE_REFLECTION_ONLY_LOAD)
FCClassElement("WindowsRuntimeMetadata", "System.Runtime.InteropServices.WindowsRuntime", gWindowsRuntimeMetadata)
#endif
#include "eeconfig.h"
#include "method.hpp"
-#ifndef FEATURE_CORECLR
-#include <xmlparser.h>
-#include <mscorcfg.h>
-#include "eeconfigfactory.h"
-#endif
#ifdef FEATURE_FUSION
#include "fusionsetup.h"
#endif
#ifdef FEATURE_WIN_DB_APPCOMPAT
#include "QuirksApi.h"
#endif
-#ifdef FEATURE_CORECLR
#include "configuration.h"
-#endif
using namespace clr;
INDEBUG(fStressLog = true;)
-#ifdef FEATURE_CORECLR
fVerifyAllOnLoad = false;
-#endif
#ifdef _DEBUG
fExpandAllOnLoad = false;
fDebuggable = false;
}
bool gcConcurrentWasForced = false;
-#ifdef FEATURE_CORECLR
// The CLRConfig value for UNSUPPORTED_gcConcurrent defaults to -1, and treats any
// positive value as 'forcing' concurrent GC to be on. Because the standard logic
// for mapping a DWORD CLRConfig to a boolean configuration treats -1 as true (just
// like any other nonzero value), we will explicitly check the DWORD later if this
// check returns false.
gcConcurrentWasForced = Configuration::GetKnobBooleanValue(W("System.GC.Concurrent"), false);
-#endif
int gcConcurrentConfigVal = 0;
if (!gcConcurrentWasForced)
#endif
iGCForceCompact = GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_gcForceCompact, iGCForceCompact);
-#ifdef FEATURE_CORECLR
iGCNoAffinitize = Configuration::GetKnobBooleanValue(W("System.GC.NoAffinitize"),
CLRConfig::UNSUPPORTED_GCNoAffinitize);
iGCHeapCount = Configuration::GetKnobDWORDValue(W("System.GC.HeapCount"), CLRConfig::UNSUPPORTED_GCHeapCount);
-#else
- iGCNoAffinitize = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_GCNoAffinitize);
- iGCHeapCount = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_GCHeapCount);
-#endif
fStressLog = GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_StressLog, fStressLog) != 0;
fForceEnc = GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_ForceEnc, fForceEnc) != 0;
fPInvokeRestoreEsp = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Jit_NetFx40PInvokeStackResilience);
#endif
-#ifndef FEATURE_CORECLR
- // These two values respect the Shim's policy of favoring config files over registry settings.
- fLegacyNullReferenceExceptionPolicy = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::UNSUPPORTED_legacyNullReferenceExceptionPolicy,
- fLegacyNullReferenceExceptionPolicy) != 0);
- fLegacyUnhandledExceptionPolicy = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::UNSUPPORTED_legacyUnhandledExceptionPolicy,
- fLegacyUnhandledExceptionPolicy) != 0);
-
-#ifdef FEATURE_CORRUPTING_EXCEPTIONS
- // Check if the user has overriden how Corrupted State Exceptions (CSE) will be handled. If the
- // <runtime> section of app.exe.config has "legacyCorruptedStateExceptionsPolicy" set to 1, then
- // V4 runtime will treat CSE in the same fashion as V2.
- fLegacyCorruptedStateExceptionsPolicy = (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_legacyCorruptedStateExceptionsPolicy) != 0);
-#endif // FEATURE_CORRUPTING_EXCEPTIONS
-
- fLegacyVirtualMethodCallVerification = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_legacyVirtualMethodCallVerification,
- fLegacyVirtualMethodCallVerification,
- REGUTIL::COR_CONFIG_ALL, TRUE,
- CONFIG_SYSTEMONLY) != 0);
-
- fLegacyApartmentInitPolicy = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_legacyApartmentInitPolicy,
- fLegacyApartmentInitPolicy) != 0);
-
- fLegacyComHierarchyVisibility = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_legacyComHierarchyVisibility,
- fLegacyComHierarchyVisibility) != 0);
-
- fLegacyComVTableLayout = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_legacyComVTableLayout,
- fLegacyComVTableLayout) != 0);
- fNewComVTableLayout = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_newComVTableLayout,
- fNewComVTableLayout) != 0);
-
- if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_legacyImpersonationPolicy) != 0)
- iImpersonationPolicy = IMP_NOFLOW;
- else if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_alwaysFlowImpersonationPolicy) != 0)
- iImpersonationPolicy = IMP_ALWAYSFLOW;
-
- fLegacyLoadMscorsnOnStartup = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::UNSUPPORTED_legacyLoadMscorsnOnStartup,
- fLegacyLoadMscorsnOnStartup) != 0);
- fBypassStrongNameVerification = (GetConfigDWORDFavoringConfigFile_DontUse_(W("bypassTrustedAppStrongNames"), fBypassStrongNameVerification) != 0) && // App opted in
- (GetConfigDWORD_DontUse_(SN_CONFIG_BYPASS_POLICY_W, TRUE, REGUTIL::COR_CONFIG_MACHINE) != 0); // And the machine policy allows for bypass
- fGeneratePublisherEvidence = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_generatePublisherEvidence, fGeneratePublisherEvidence) != 0);
- fEnforceFIPSPolicy = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_enforceFIPSPolicy, fEnforceFIPSPolicy) != 0);
- fLegacyHMACMode = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_legacyHMACMode, fLegacyHMACMode) != 0);
-
- fCacheBindingFailures = !(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_disableCachingBindingFailures));
- fUseLegacyIdentityFormat =
-#ifdef FEATURE_APPX
- AppX::IsAppXProcess() ||
-#endif
- (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_useLegacyIdentityFormat) != 0);
- fDisableFusionUpdatesFromADManager = (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_disableFusionUpdatesFromADManager) != 0);
- fDisableCommitThreadStack = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_disableCommitThreadStack, fDisableCommitThreadStack) != 0);
- fProbeForStackOverflow = !(CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_disableStackOverflowProbing));
-#endif // FEATURE_CORECLR
#ifdef _DEBUG
fDebuggable = (GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_JitDebuggable, fDebuggable) != 0);
fEnableRCWCleanupOnSTAShutdown = (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_EnableRCWCleanupOnSTAShutdown) != 0);
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_CORECLR
//Eager verification of all assemblies.
fVerifyAllOnLoad = (GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_VerifyAllOnLoad, fVerifyAllOnLoad) != 0);
-#endif //FEATURE_CORECLR
#ifdef _DEBUG
fExpandAllOnLoad = (GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_ExpandAllOnLoad, fExpandAllOnLoad) != 0);
m_fInteropLogArguments = (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_InteropLogArguments) != 0);
#ifdef FEATURE_PREJIT
-#ifndef FEATURE_CORECLR
- DWORD iNgenHardBindOverride = GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_HardPrejitEnabled, iNgenHardBind);
- _ASSERTE(iNgenHardBindOverride < NGEN_HARD_BIND_COUNT);
- if (iNgenHardBindOverride < NGEN_HARD_BIND_COUNT)
- iNgenHardBind = NgenHardBindType(iNgenHardBindOverride);
-#endif
#ifdef _DEBUG
dwNgenForceFailureMask = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NgenForceFailureMask);
dwNgenForceFailureCount = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NgenForceFailureCount);
return g_dwHostConfigFile;
}
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE) // unimpactful install --> no config files
-
-/**************************************************************/
-static void MessageBoxParseError(HRESULT hr, __in_z LPCWSTR wszFile);
-
-#define IfFailParseError(FILE, ISAPPCONFIG, ...) \
- do \
- { \
- /* On error, always show an error dialog and return an error result when process is immersive; */ \
- /* otherwise show dialog (conditionally for App config) and swallow error. */ \
- if (FAILED(hr = (__VA_ARGS__)) && (!(ISAPPCONFIG) || AppX::IsAppXProcess() || GetConfigDWORDInternal_DontUse_(CLRConfig::EXTERNAL_NotifyBadAppCfg,false))) \
- { \
- MessageBoxParseError(hr, FILE); \
- if (AppX::IsAppXProcess()) \
- { /* Fail on bad config in AppX process. */ \
- return hr; \
- } \
- else \
- { \
- hr = S_FALSE; \
- } \
- } \
- } while (false)
-
-/**************************************************************/
-HRESULT EEConfig::SetupConfiguration()
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- } CONTRACTL_END;
-
- WCHAR version[_MAX_PATH];
- DWORD dwVersion = _MAX_PATH;
-
- HRESULT hr = S_OK;
- // Get the version location
- IfFailRet(GetCORVersionInternal(version, _MAX_PATH, & dwVersion));
-
- // See if the environment has specified an XML file
- NewArrayHolder<WCHAR> file(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CONFIG));
- if(file != NULL)
- {
- IfFailParseError(file, false, AppendConfigurationFile(file, version));
- }
-
- // We need to read configuration information from 3 sources... the app config file, the
- // host supplied config file, and the machine.config file. The order in which we
- // read them are very import. If the different config sources specify the same config
- // setting, we will use the setting of the first one read.
- //
- // In the pecking order, machine.config should always have the final say. The host supplied config
- // file should follow, and lastly, the app config file.
- //
- // Note: the order we read them is not the order they are published. Need to read the AppConfig
- // first so that we can decide if we should import machine.config (yes in Classic, typically no
- // in AppX). We still publish in the order required as described above.
-
- enum
- {
- MachineConfig = 0,
- HostConfig = 1,
- AppConfig = 2,
- NumConfig = 3,
- };
-
- ConfigSource * rgpSources[NumConfig] = { nullptr };
-
- // Create ConfigSource objects for all config files.
- for (size_t i = 0; i < NumConfig; ++i)
- {
- rgpSources[i] = new (nothrow) ConfigSource();
- if (rgpSources[i] == NULL)
- {
- while (i != 0)
- {
- --i;
- delete rgpSources[i];
- rgpSources[i] = nullptr;
- }
- return E_OUTOFMEMORY;
- }
- }
-
- // Publish ConfigSource objects in required order. It's ok that the file contents are imported below,
- // since we're in EEStartup and this data cannot be accessed by any other threads yet.
- for (size_t i = 0; i < NumConfig; ++i)
- {
- m_Configuration.Append(rgpSources[i]);
- }
-
- // ----------------------------------------------------
- // Import the app.config file, or in the case of an
- // AppX process check to make sure no app.config file
- // exists unless launched with AO_DESIGNMODE.
- // ----------------------------------------------------
-
- do
- {
- size_t cchProcExe=0;
- PathString wzProcExe;
- EX_TRY
- {
-
-
-
- // Get name of file used to create process
- if (g_pCachedModuleFileName)
- {
- wzProcExe.Set(g_pCachedModuleFileName);
- cchProcExe = wzProcExe.GetCount();
- }
- else
- {
- cchProcExe = WszGetModuleFileName(NULL, wzProcExe);
-
- if (cchProcExe == 0)
- {
- hr = HRESULT_FROM_GetLastError();
- break;
- }
- }
-
- if (cchProcExe != 0)
- {
- wzProcExe.Append(CONFIGURATION_EXTENSION);
-
- if (AppX::IsAppXProcess() && !AppX::IsAppXDesignMode())
- {
- if (clr::fs::Path::Exists(wzProcExe))
- {
- hr = CLR_E_APP_CONFIG_NOT_ALLOWED_IN_APPX_PROCESS;
- break;
- }
- }
- }
- }
- EX_CATCH_HRESULT(hr);
- if (cchProcExe != 0)
- {
- IfFailParseError(wzProcExe, true, AppendConfigurationFile(wzProcExe, version));
-
- // We really should return a failure hresult if the app config file is bad, but that
- // would be a breaking change. Not sure if it's worth it yet.
- hr = S_OK;
- break;
- }
- } while (false);
-
-
- if (hr != S_OK)
- return hr;
- // ----------------------------------------------------
- // Import machine.config, if needed.
- // ----------------------------------------------------
- if (!AppX::IsAppXProcess() || AppX::IsAppXDesignMode())
- {
- WCHAR wzSystemDir[_MAX_PATH];
- DWORD cchSystemDir = COUNTOF(wzSystemDir);
- IfFailRet(GetInternalSystemDirectory(wzSystemDir, &cchSystemDir));
-
- // cchSystemDir already includes the NULL
- if(cchSystemDir + StrLen(MACHINE_CONFIGURATION_FILE) <= _MAX_PATH)
- {
- IfFailRet(StringCchCat(wzSystemDir, COUNTOF(wzSystemDir), MACHINE_CONFIGURATION_FILE));
-
- // CLR_STARTUP_OPT:
- // The machine.config file can be very large. We cannot afford
- // to parse all of it at CLR startup time.
- //
- // Accordingly, we instruct the XML parser to stop parsing the
- // machine.config file when it sees the end of the
- // <runtime>...</runtime> section that holds our data (if any).
- //
- // By construction, this section is now placed near the top
- // of machine.config.
- //
- IfFailParseError(wzSystemDir, false, ImportConfigurationFile(
- rgpSources[MachineConfig]->Table(), wzSystemDir, version, stopAfterRuntimeSection));
-
- if (hr == S_FALSE) // means that we couldn't find machine.config
- hr = S_OK;
- }
- }
-
- // ----------------------------------------------------
- // Import the host supplied config file, if needed.
- // ----------------------------------------------------
- // Cannot host an AppX managed process, so no need to check devModeEnabled.
- if (!AppX::IsAppXProcess())
- {
- if (GetProcessBindingFile() != NULL && GetSizeOfProcessBindingFile() > 0)
- {
- IfFailRet(ImportConfigurationFile(
- rgpSources[HostConfig]->Table(), GetProcessBindingFile(), version));
- }
- }
-
- return hr;
-}
-
-//
-// There was an error 'hr' parsing the file 'wszFile'.
-// Pop up a MessageBox reporting the error, unless the config setting
-// 'NoGuiFromShim' is in effect.
-//
-static void MessageBoxParseError(HRESULT hr, __in_z LPCWSTR wszFile)
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(FAILED(hr));
- } CONTRACTL_END;
-
- if (!REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_NoGuiFromShim, FALSE))
- {
- EEMessageBoxCatastrophic(IDS_EE_CONFIGPARSER_ERROR, IDS_EE_CONFIGPARSER_ERROR_CAPTION, wszFile, hr);
- }
-}
-
-/**************************************************************/
-
-STDAPI GetXMLObjectEx(IXMLParser **ppv);
-
-HRESULT EEConfig::ImportConfigurationFile(
- ConfigStringHashtable* pTable,
- LPCWSTR pszFileName,
- LPCWSTR version,
- ParseCtl parseCtl)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pTable));
- PRECONDITION(CheckPointer(pszFileName));
- PRECONDITION(CheckPointer(version));
- INJECT_FAULT(return E_OUTOFMEMORY);
- } CONTRACTL_END;
-
- NonVMComHolder<IXMLParser> pIXMLParser(NULL);
- NonVMComHolder<IStream> pFile(NULL);
- NonVMComHolder<EEConfigFactory> factory(NULL);
-
- HRESULT hr = CreateConfigStreamHelper(pszFileName, &pFile);
- if(FAILED(hr)) goto Exit;
-
- hr = GetXMLObjectEx(&pIXMLParser);
- if(FAILED(hr)) goto Exit;
-
- factory = new (nothrow) EEConfigFactory(pTable, version, parseCtl);
-
- if ( ! factory) {
- hr = E_OUTOFMEMORY;
- goto Exit;
- }
- factory->AddRef(); // RefCount = 1
-
-
- hr = pIXMLParser->SetInput(pFile); // filestream's RefCount=2
- if ( ! SUCCEEDED(hr))
- goto Exit;
-
- hr = pIXMLParser->SetFactory(factory); // factory's RefCount=2
- if ( ! SUCCEEDED(hr))
- goto Exit;
-
- {
- CONTRACT_VIOLATION(ThrowsViolation); // @todo: Run() throws!
- hr = pIXMLParser->Run(-1);
- }
-
-Exit:
- if (hr == (HRESULT) XML_E_MISSINGROOT)
- hr = S_OK;
- else if (Assembly::FileNotFound(hr))
- hr = S_FALSE;
-
- return hr;
-}
-
-HRESULT EEConfig::AppendConfigurationFile(
- LPCWSTR pszFileName,
- LPCWSTR version,
- ParseCtl parseCtl)
-{
- LIMITED_METHOD_CONTRACT;
- HRESULT hr = S_OK;
-
- ConfigStringHashtable* pTable = m_Configuration.Append();
- IfNullRet(pTable);
-
- return ImportConfigurationFile(pTable, pszFileName, version, parseCtl);
-}
-
-
-#endif // FEATURE_CORECLR && !CROSSGEN_COMPILE
bool EEConfig::RequireZap(LPCUTF8 assemblyName) const
{
}
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_CORECLR
bool VerifyModulesOnLoad(void) const { LIMITED_METHOD_CONTRACT; return fVerifyAllOnLoad; }
-#endif
#ifdef _DEBUG
bool ExpandModulesOnLoad(void) const { LIMITED_METHOD_CONTRACT; return fExpandAllOnLoad; }
#endif //_DEBUG
bool m_fDeveloperInstallation; // We are on a developers machine
bool fAppDomainUnload; // Enable appdomain unloading
-#ifdef FEATURE_CORECLR
bool fVerifyAllOnLoad; // True if we want to verify all methods in an assembly at load time.
-#endif //FEATURE_CORECLR
DWORD dwADURetryCount;
#endif
public:
-#ifndef FEATURE_CORECLR // unimpactful install --> no config files
- HRESULT ImportConfigurationFile(
- ConfigStringHashtable* pTable,
- LPCWSTR pszFileName,
- LPCWSTR version,
- ParseCtl parseCtl = parseAll);
-
- HRESULT AppendConfigurationFile(
- LPCWSTR pszFileName,
- LPCWSTR version,
- ParseCtl parseCtl = parseAll);
-
- HRESULT SetupConfiguration();
-#endif // FEATURE_CORECLR
HRESULT GetConfiguration_DontUse_(__in_z LPCWSTR pKey, ConfigSearch direction, __deref_out_opt LPCWSTR* value);
LPCWSTR GetProcessBindingFile(); // All flavors must support this method
m_ActionOnFailure[FAIL_NonCriticalResource] = eThrowException;
m_ActionOnFailure[FAIL_OrphanedLock] = eNoAction;
m_ActionOnFailure[FAIL_FatalRuntime] = eRudeExitProcess;
-#ifdef FEATURE_CORECLR
// For CoreCLR, initialize the default action for AV processing to all
// all kind of code to catch AV exception. If the host wants, they can
// specify a different action for this.
m_ActionOnFailure[FAIL_AccessViolation] = eNoAction;
-#endif // FEATURE_CORECLR
m_ActionOnFailure[FAIL_StackOverflow] = eRudeExitProcess;
m_ActionOnFailure[FAIL_CodeContract] = eThrowException;
m_unhandledExceptionPolicy = eRuntimeDeterminedPolicy;
return action >= eUnloadAppDomain &&
action < MaxPolicyAction;
case FAIL_AccessViolation:
-#ifdef FEATURE_CORECLR
// Allowed actions on failure are:
//
// eNoAction or eRudeExitProcess.
return ((action == eNoAction) || (action == eRudeExitProcess));
-#else // !FEATURE_CORECLR
- // FAIL_AccessViolation is defined for the desktop so that
- // if any more definitions are added after it, their value
- // should remain constant irrespective of whether its the
- // desktop CLR or CoreCLR.
- //
- // That said, currently, Desktop CLR does not support
- // FAIL_AccessViolation. Thus, any calls which use
- // this failure are not allowed.
- return FALSE;
-#endif // FEATURE_CORECLR
case FAIL_StackOverflow:
return action >= eRudeUnloadAppDomain &&
action < MaxPolicyAction;
// runtime in a process with many. We need to give the other runtimes a chance to exit
// cleanly. If we can't make the call, or if the call fails for some reason, then we
// simply exit the process here, which is rude to the others, but the best we can do.
-#if !defined(FEATURE_CORECLR)
- {
- ReleaseHolder<ICLRRuntimeHostInternal> pRuntimeHostInternal;
-
- HRESULT hr = g_pCLRRuntime->GetInterface(CLSID_CLRRuntimeHostInternal,
- IID_ICLRRuntimeHostInternal,
- &pRuntimeHostInternal);
-
- if (SUCCEEDED(hr))
- {
- pRuntimeHostInternal->ShutdownAllRuntimesThenExit(exitCode);
- LOG((LF_EH, LL_INFO10, "ExitProcessViaShim: shim returned... exiting now.\n"));
- }
- }
-#endif // !FEATURE_CORECLR
ExitProcess(exitCode);
}
#include "../dlls/mscorrc/resource.h"
-#if defined(FEATURE_CORECLR)
#include "getproductversionnumber.h"
-#endif // FEATURE_CORECLR
//---------------------------------------------------------------------------------------
//
ssMessage.Clear();
if(!ssMessage.LoadResource(CCompRC::Optional, IDS_ER_FRAMEWORK_VERSION))
-#ifndef FEATURE_CORECLR
- m_Description.Append(W("Framework Version: "));
-#else // FEATURE_CORECLR
m_Description.Append(W("CoreCLR Version: "));
-#endif // !FEATURE_CORECLR
else
{
m_Description.Append(ssMessage);
}
BOOL fHasVersion = FALSE;
-#ifndef FEATURE_CORECLR
- if (GetCLRModule() != NULL)
- {
- WCHAR buffer[80];
- DWORD length;
- if (SUCCEEDED(GetCORVersionInternal(buffer, 80, &length)))
- {
- m_Description.Append(buffer);
- m_Description.Append(W("\n"));
- fHasVersion = TRUE;
- }
- }
-#else // FEATURE_CORECLR
DWORD dwMajorVersion = 0;
DWORD dwMinorVersion = 0;
DWORD dwBuild = 0;
EventReporter::GetCoreCLRInstanceProductVersion(&dwMajorVersion, &dwMinorVersion, &dwBuild, &dwRevision);
m_Description.AppendPrintf(W("%lu.%lu.%lu.%lu\n"),dwMajorVersion, dwMinorVersion, dwBuild, dwRevision);
fHasVersion = TRUE;
-#endif // !FEATURE_CORECLR
if (!fHasVersion)
{
gc.throwable = pThread->GetThrowable();
_ASSERTE(gc.throwable != NULL);
-#ifdef FEATURE_CORECLR
// On CoreCLR, managed code execution happens in non-default AppDomains and all threads have an AD transition
// at their base from DefaultDomain to the target Domain before they start executing managed code. Thus, when
// an exception goes unhandled in a non-default AppDomain on a reverse pinvoke thread, the original exception details are copied
}
}
else
-#endif // FEATURE_CORECLR
{
if (IsException(gc.throwable->GetMethodTable()))
{
}
}
-#if defined(FEATURE_CORECLR)
// This function will return the product version of CoreCLR
// instance we are executing in.
void EventReporter::GetCoreCLRInstanceProductVersion(DWORD * pdwMajor, DWORD * pdwMinor, DWORD * pdwBuild, DWORD * pdwRevision)
LOG((LF_CORDB, LL_INFO100, "GetCoreCLRInstanceVersion: Unable to get CoreCLR version.\n"));
}
}
-#endif // FEATURE_CORECLR
// Flag to indicate if the buffer is full
BOOL fBufferFull;
-#ifdef FEATURE_CORECLR
static void GetCoreCLRInstanceProductVersion(DWORD * pdwMajor, DWORD * pdwMinor, DWORD * pdwBuild, DWORD * pdwRevision);
-#endif // FEATURE_CORECLR
public:
// Construct
EventRegisterMicrosoft_Windows_DotNETRuntimeRundown();
// Stress Log ETW events are available only on the desktop version of the runtime
-#ifndef FEATURE_CORECLR
- EventRegisterMicrosoft_Windows_DotNETRuntimeStress();
-#endif // !FEATURE_CORECLR
MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context.RegistrationHandle = Microsoft_Windows_DotNETRuntimeHandle;
MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context.RegistrationHandle = Microsoft_Windows_DotNETRuntimePrivateHandle;
MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context.RegistrationHandle = Microsoft_Windows_DotNETRuntimeRundownHandle;
-#ifndef FEATURE_CORECLR
- MICROSOFT_WINDOWS_DOTNETRUNTIME_STRESS_PROVIDER_Context.RegistrationHandle = Microsoft_Windows_DotNETRuntimeStressHandle;
-#endif // !FEATURE_CORECLR
return S_OK;
}
EventUnregisterMicrosoft_Windows_DotNETRuntime();
EventUnregisterMicrosoft_Windows_DotNETRuntimePrivate();
EventUnregisterMicrosoft_Windows_DotNETRuntimeRundown();
-#ifndef FEATURE_CORECLR
- EventUnregisterMicrosoft_Windows_DotNETRuntimeStress();
-#endif // !FEATURE_CORECLR
return S_OK;
}
g_fEEComActivatedStartup || //CLR started as a COM object
g_fEEOtherStartup ); //In case none of the 4 above mentioned cases are true for example ngen, ildasm then we asssume its a "other" startup
-#ifdef FEATURE_CORECLR
Sku = ETW::InfoLog::InfoStructs::CoreCLR;
-#else
- Sku = ETW::InfoLog::InfoStructs::DesktopCLR;
-#endif //FEATURE_CORECLR
//version info for clr.dll
USHORT vmMajorVersion = VER_MAJORVERSION;
PCWSTR lpwszCommandLine = W("");
-#ifndef FEATURE_CORECLR
- startupFlags = CorHost2::GetStartupFlags();
-
- // Some of the options specified by the startup flags can be overwritten by config files.
- // Strictly speaking since the field in this event is called StartupFlags there's nothing
- // wrong with just showing the actual startup flags but it makes it less useful (a more
- // appropriate name for the field is StartupOptions).
- startupFlags &= ~STARTUP_CONCURRENT_GC;
- if (g_pConfig->GetGCconcurrent())
- startupFlags |= STARTUP_CONCURRENT_GC;
-
- if (g_pConfig->DefaultSharePolicy() != AppDomain::SHARE_POLICY_UNSPECIFIED)
- {
- startupFlags &= ~STARTUP_LOADER_OPTIMIZATION_MASK;
- startupFlags |= g_pConfig->DefaultSharePolicy() << 1;
- }
-
- startupFlags &= ~STARTUP_LEGACY_IMPERSONATION;
- startupFlags &= ~STARTUP_ALWAYSFLOW_IMPERSONATION;
- if (g_pConfig->ImpersonationMode() == IMP_NOFLOW)
- startupFlags |= STARTUP_LEGACY_IMPERSONATION;
- else if (g_pConfig->ImpersonationMode() == IMP_ALWAYSFLOW)
- startupFlags |= STARTUP_ALWAYSFLOW_IMPERSONATION;
-#endif //!FEATURE_CORECLR
// Determine the startupmode
if(g_fEEIJWStartup)
VOID ETW::SecurityLog::StrongNameVerificationStart(DWORD dwInFlags, __in LPWSTR strFullyQualifiedAssemblyName)
{
WRAPPER_NO_CONTRACT;
-#ifndef FEATURE_CORECLR
- FireEtwStrongNameVerificationStart_V1(dwInFlags, 0, strFullyQualifiedAssemblyName, GetClrInstanceId());
-#endif // !FEATURE_CORECLR
}
VOID ETW::SecurityLog::StrongNameVerificationStop(DWORD dwInFlags,ULONG result, __in LPWSTR strFullyQualifiedAssemblyName)
{
WRAPPER_NO_CONTRACT;
-#ifndef FEATURE_CORECLR
- FireEtwStrongNameVerificationStop_V1(dwInFlags, result, strFullyQualifiedAssemblyName, GetClrInstanceId());
-#endif // !FEATURE_CORECLR
}
/****************************************************************************/
SetErrorMode(lastErrorMode | SEM_NOGPFAULTERRORBOX);
LOG((LF_EH, LL_INFO100, "DisableOSWatson: SetErrorMode = 0x%x\n", lastErrorMode | SEM_NOGPFAULTERRORBOX));
-#ifndef FEATURE_CORECLR
- // CoreCLR is always hosted and so this condition is always false
- if (RunningOnWin7() && !CLRHosted())
- {
- typedef DWORD (WINAPI * GetThreadErrorModeFnPtr)(void);
- typedef BOOL (WINAPI * SetThreadErrorModeFnPtr)(DWORD, LPDWORD);
- GetThreadErrorModeFnPtr pFnGetThreadErrorMode;
- SetThreadErrorModeFnPtr pFnSetThreadErrorMode;
-
- HINSTANCE hKernel32 = WszGetModuleHandle(WINDOWS_KERNEL32_DLLNAME_W);
- if (hKernel32 != NULL)
- {
- pFnGetThreadErrorMode = (GetThreadErrorModeFnPtr)GetProcAddress(hKernel32, "GetThreadErrorMode");
- pFnSetThreadErrorMode = (SetThreadErrorModeFnPtr)GetProcAddress(hKernel32, "SetThreadErrorMode");
-
- // GetThreadErrorMode and SetThreadErrorMode should be available on Win7.
- _ASSERTE((pFnGetThreadErrorMode != NULL) && (pFnSetThreadErrorMode != NULL));
- if ((pFnGetThreadErrorMode != NULL) && (pFnSetThreadErrorMode != NULL))
- {
- DWORD dwOldMode = (*pFnGetThreadErrorMode)();
- (*pFnSetThreadErrorMode)(dwOldMode | SEM_NOGPFAULTERRORBOX, &dwOldMode);
- LOG((LF_EH, LL_INFO100, "DisableOSWatson: SetThreadErrorMode = 0x%x\n", dwOldMode | SEM_NOGPFAULTERRORBOX));
- }
- }
- }
-#endif // FEATURE_CORECLR
}
return EXCEPTION_CONTINUE_SEARCH;
} // LONG DefaultCatchNoSwallowFilter()
-#if defined(FEATURE_CORECLR)
// Note: This is used only for CoreCLR on WLC.
//
// We keep a pointer to the previous unhandled exception filter. After we install, we use
// yet and having installed it but the original handler was NULL.
static LPTOP_LEVEL_EXCEPTION_FILTER g_pOriginalUnhandledExceptionFilter = (LPTOP_LEVEL_EXCEPTION_FILTER)-1;
#define FILTER_NOT_INSTALLED (LPTOP_LEVEL_EXCEPTION_FILTER) -1
-#endif // defined(FEATURE_CORECLR)
BOOL InstallUnhandledExceptionFilter() {
//
if (pThread && (pThread->HasThreadStateNC(Thread::TSNC_ProcessedUnhandledException) || pThread->HasThreadStateNC(Thread::TSNC_AppDomainContainUnhandled)))
{
-#ifdef FEATURE_CORECLR
// This assert shouldnt be hit in CoreCLR since:
//
// 1) It has no concept of managed entry point that is invoked by the shim. You can
{
_ASSERTE(!"How come a thread with TSNC_ProcessedUnhandledException state entered the UEF on CoreCLR?");
}
-#endif // FEATURE_CORECLR
LOG((LF_EH, LL_INFO100, "InternalUnhandledExceptionFilter_Worker: have already processed unhandled exception for this thread.\n"));
return EXCEPTION_CONTINUE_SEARCH;
{
BOOL fIsProcessTerminating = TRUE;
-#ifdef FEATURE_CORECLR
// In CoreCLR, we can be asked to not let an exception go unhandled on managed threads in a given AppDomain.
// If the exception reaches the top of the thread's stack, we simply deliver AppDomain's UnhandledException event and
// return back to the filter, instead of letting the process terminate because of unhandled exception.
fIsProcessTerminating = !(pParam->pThread->GetDomain()->IgnoreUnhandledExceptions());
else
fIsProcessTerminating = !(pParam->pThread->HasThreadStateNC(Thread::TSNC_IgnoreUnhandledExceptions));
-#endif // FEATURE_CORECLR
#ifndef FEATURE_PAL
// Setup the watson bucketing details for UE processing.
// Send notifications to the AppDomains.
NotifyAppDomainsOfUnhandledException(pParam->pExceptionInfo, NULL, useLastThrownObject, fIsProcessTerminating /*isTerminating*/);
-#ifdef FEATURE_CORECLR
// If the process is not terminating, then return back to the filter and ask it to execute
if (!fIsProcessTerminating)
{
pParam->retval = EXCEPTION_EXECUTE_HANDLER;
goto lDone;
}
-#endif // FEATURE_CORECLR
}
else
{
//
// Note: Also see the conditional UEF registration with the OS in EEStartupHelper.
-#ifdef FEATURE_CORECLR
// We would be here only on CoreCLR for WLC since we dont register
// the UEF with the OS for SL.
if (g_pOriginalUnhandledExceptionFilter != FILTER_NOT_INSTALLED
{
STRESS_LOG1(LF_EH, LL_INFO100, "InternalUnhandledExceptionFilter: Not chaining back to previous UEF at address %p on CoreCLR!\n", g_pOriginalUnhandledExceptionFilter);
}
-#endif // FEATURE_CORECLR
return retval;
// Returns
// the result of calling InternalUnhandledExceptionFilter
//------------------------------------------------------------------------------
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#if !defined(FEATURE_PAL)
#pragma code_seg(push, uef, CLR_UEF_SECTION_NAME)
#endif // FEATURE_CORECLR && !FEATURE_PAL
LONG __stdcall COMUnhandledExceptionFilter( // EXCEPTION_CONTINUE_SEARCH or EXCEPTION_CONTINUE_EXECUTION
return retVal;
}
-#ifndef FEATURE_CORECLR
-#ifdef _DEBUG
- // V4 onwards, we will reach here in the UEF only on the following conditions:
- //
- // 1) Faulting address is in native code on a reverse pinvoke thread. An example is an exception that escaped
- // out of the reverse pinvoke thread but was caught in the native part of the thread. The native part then
- // had another exception that went unhandled. The difference between this and (3) below is that
- // we have a thread object here but not in (3).
- //
- // An exception from PInvoke, that is never caught/rethrown in managed code and goes unhandled, also falls
- // in this category.
- //
- // 2) The exception escaped out of a reverse pinvoke thread and went unhandled.
- //
- // 3) Faulting thread was never seen by the runtime. An example is a another native thread
- // which the user code created that had unhandled exception.
- //
- // 4) A corrupting exception may become unhandled.
- //
- // This is not applicable to CoreCLR, as this unhandled exception filter is always set up, and all hardware exceptions in
- // managed code, including those that are not process-corrupting, such as integer division by zero, will end up here.
-
- // Assert these conditions here - we shouldnt be here for any other unhandled exception processing.
- Thread *pThread = GetThread();
- if ((pThread != NULL) && // condition 3
- !(pThread->GetExceptionState()->IsExceptionInProgress() &&
- pThread->GetExceptionState()->GetFlags()->ReversePInvokeEscapingException()) && // condition 2
- (ExecutionManager::IsManagedCode((PCODE)pExceptionInfo->ExceptionRecord->ExceptionAddress))) // condition 1
- {
-#ifdef FEATURE_CORRUPTING_EXCEPTIONS
- if (!CEHelper::IsProcessCorruptedStateException(pExceptionInfo->ExceptionRecord->ExceptionCode)) // condition 4
- {
- GCX_COOP();
- _ASSERTE(CEHelper::IsProcessCorruptedStateException(pThread->GetThrowable())); // condition 4
- }
-#else // !FEATURE_CORRUPTING_EXCEPTIONS
- _ASSERTE(false);
-#endif // FEATURE_CORRUPTING_EXCEPTIONS
- }
-#endif // _DEBUG
-#endif // !FEATURE_CORECLR
retVal = InternalUnhandledExceptionFilter(pExceptionInfo);
return retVal;
} // LONG __stdcall COMUnhandledExceptionFilter()
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#if !defined(FEATURE_PAL)
#pragma code_seg(pop, uef)
#endif // FEATURE_CORECLR && !FEATURE_PAL
#ifndef FEATURE_PAL
-#ifdef FEATURE_CORECLR
// Only proceed if Watson is enabled - CoreCLR may have it disabled.
if (IsWatsonEnabled())
-#endif // FEATURE_CORECLR
{
BOOL fClearUEWatsonBucketTracker = TRUE;
PTR_EHWatsonBucketTracker pUEWatsonBucketTracker = pThread->GetExceptionState()->GetUEWatsonBucketTracker();
// appropriate exception code, or zero if the code is not a GC marker.
DWORD GetGcMarkerExceptionCode(LPVOID ip)
{
-#if defined(HAVE_GCCOVER) && defined(FEATURE_CORECLR)
+#if defined(HAVE_GCCOVER)
WRAPPER_NO_CONTRACT;
if (GCStress<cfg_any>::IsEnabled() && IsGcCoverageInterrupt(ip))
{
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_CORECLR
// CoreCLR may have watson bucketing conditionally enabled.
if (!IsWatsonEnabled())
{
return FALSE;
}
-#endif // FEATURE_CORECLR
CONTRACTL
{
{
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_CORECLR
// CoreCLR may have watson bucketing conditionally enabled.
if (!IsWatsonEnabled())
{
return FALSE;
}
-#endif // FEATURE_CORECLR
CONTRACTL
{
{
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_CORECLR
// CoreCLR may have watson bucketing conditionally enabled.
if (!IsWatsonEnabled())
{
return;
}
-#endif // FEATURE_CORECLR
CONTRACTL
{
BOOL fResult = TRUE;
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_CORECLR
// On CoreCLR, Watson may not be enabled. Thus, we should
// skip this.
if (!IsWatsonEnabled())
{
return fResult;
}
-#endif // FEATURE_CORECLR
CONTRACTL
{
{
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_CORECLR
// On CoreCLR, Watson may not be enabled. Thus, we should
// skip this.
if (!IsWatsonEnabled())
{
return;
}
-#endif // FEATURE_CORECLR
CONTRACTL
{
{
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_CORECLR
// On CoreCLR, Watson may not be enabled. Thus, we should
// skip this.
if (!IsWatsonEnabled())
{
return;
}
-#endif // FEATURE_CORECLR
CONTRACTL
{
// This is *also* invoked from the DAC when buckets are requested.
PTR_VOID EHWatsonBucketTracker::RetrieveWatsonBuckets()
{
-#if defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE)
+#if !defined(DACCESS_COMPILE)
if (!IsWatsonEnabled())
{
return NULL;
{
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_CORECLR
if (!IsWatsonEnabled())
{
return;
}
-#endif // FEATURE_CORECLR
CONTRACTL
{
BOOL InstallUnhandledExceptionFilter();
void UninstallUnhandledExceptionFilter();
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#if !defined(FEATURE_PAL)
// Section naming is a strategy by itself. Ideally, we could have named the UEF section
// ".text$zzz" (lowercase after $ is important). What the linker does is look for the sections
// that has the same name before '$' sign. It combines them together but sorted in an alphabetical
}
#endif // FEATURE_CORRUPTING_EXCEPTIONS
-#ifdef FEATURE_CORECLR
{
// Switch to COOP mode since we are going to work
// with throwable
}
}
}
-#endif // FEATURE_CORECLR
#ifndef FEATURE_PAL // Watson is on Windows only
// Setup bucketing details for nested exceptions (rethrow and non-rethrow) only if we are in the first pass
}
#endif // PROFILING_SUPPORTED
-#ifdef FEATURE_CORECLR
// This change was added late in Windows Phone 8, so we want to keep it minimal.
// We should consider refactoring this later, as we've got a lot of dead code here now on CoreCLR.
dwTimeout = INFINITE;
maxTotalWait = INFINITE;
-#endif // FEATURE_CORECLR
while (1) {
struct Param
PTR_Object m_LastThrownObjectInParentContext;
ULONG_PTR m_LockCount; // Number of locks the thread takes
// before the transition.
-#ifndef FEATURE_CORECLR
- ULONG_PTR m_CriticalRegionCount;
-#endif // !FEATURE_CORECLR
VPTR_VTABLE_CLASS(ContextTransitionFrame, Frame)
public:
return (DWORD) m_LockCount;
}
-#ifndef FEATURE_CORECLR
- void SetCriticalRegionCount(DWORD criticalRegionCount)
- {
- LIMITED_METHOD_CONTRACT;
- m_CriticalRegionCount = criticalRegionCount;
- }
- DWORD GetCriticalRegionCount()
- {
- LIMITED_METHOD_CONTRACT;
- return (DWORD) m_CriticalRegionCount;
- }
-#endif // !FEATURE_CORECLR
// Let debugger know that we're transitioning between AppDomains.
ETransitionType GetTransitionType()
, m_ReturnExecutionContext(NULL)
, m_LastThrownObjectInParentContext(NULL)
, m_LockCount(0)
-#ifndef FEATURE_CORECLR
- , m_CriticalRegionCount(0)
-#endif // !FEATURE_CORECLR
{
LIMITED_METHOD_CONTRACT;
}
size_t job_physical_memory_limit = (size_t)MAX_PTR;
BOOL in_job_p = FALSE;
-#ifdef FEATURE_CORECLR
HINSTANCE hinstKernel32 = 0;
-#else
- HINSTANCE hinstPsapi = 0;
-#endif
PIS_PROCESS_IN_JOB GCIsProcessInJob = 0;
PQUERY_INFORMATION_JOB_OBJECT GCQueryInformationJobObject = 0;
if (in_job_p)
{
-#ifdef FEATURE_CORECLR
hinstKernel32 = WszLoadLibrary(L"kernel32.dll");
if (!hinstKernel32)
goto exit;
GCGetProcessMemoryInfo = (PGET_PROCESS_MEMORY_INFO)GetProcAddress(hinstKernel32, "K32GetProcessMemoryInfo");
-#else
- // We need a way to get the working set in a job object and GetProcessMemoryInfo
- // is the way to get that. According to MSDN, we should use GetProcessMemoryInfo In order to
- // compensate for the incompatibility that psapi.dll introduced we are getting this dynamically.
- hinstPsapi = WszLoadLibrary(L"psapi.dll");
- if (!hinstPsapi)
- return 0;
- GCGetProcessMemoryInfo = (PGET_PROCESS_MEMORY_INFO)GetProcAddress(hinstPsapi, "GetProcessMemoryInfo");
-#endif
if (!GCGetProcessMemoryInfo)
goto exit;
{
job_physical_memory_limit = 0;
-#ifdef FEATURE_CORECLR
FreeLibrary(hinstKernel32);
-#else
- FreeLibrary(hinstPsapi);
-#endif
}
VolatileStore(&g_RestrictedPhysicalMemoryLimit, job_physical_memory_limit);
#include "field.h"
#include "gcheaputilities.h"
-#if !defined(FEATURE_CORECLR)
-inline size_t SizeInKBytes(size_t cbSize)
-{
- LIMITED_METHOD_CONTRACT;
-
- size_t cb = (cbSize % 1024) ? 1 : 0;
- return ((cbSize / 1024) + cb);
-}
-
-// IGCController
-
-HRESULT CorGCHost::_SetGCSegmentSize(SIZE_T SegmentSize)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // Sanity check the value, it must be a power of two and big enough.
- if (!GCHeapUtilities::GetGCHeap()->IsValidSegmentSize(SegmentSize))
- {
- hr = E_INVALIDARG;
- }
- else
- {
- Host_SegmentSize = SegmentSize;
- Host_fSegmentSizeSet = TRUE;
- }
-
- return (hr);
-}
-
-HRESULT CorGCHost::_SetGCMaxGen0Size(SIZE_T MaxGen0Size)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // Sanity check the value is at least large enough.
- if (!GCHeapUtilities::GetGCHeap()->IsValidGen0MaxSize(MaxGen0Size))
- {
- hr = E_INVALIDARG;
- }
- else
- {
- Host_MaxGen0Size = MaxGen0Size;
- Host_fMaxGen0SizeSet = TRUE;
- }
-
- return (hr);
-}
-
-HRESULT CorGCHost::SetGCStartupLimits(
- DWORD SegmentSize,
- DWORD MaxGen0Size)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // Set default overrides if specified by caller.
- if (SegmentSize != (DWORD) ~0 && SegmentSize > 0)
- {
- hr = _SetGCSegmentSize(SegmentSize);
- }
-
- if (SUCCEEDED(hr) && MaxGen0Size != (DWORD) ~0 && MaxGen0Size > 0)
- {
- hr = _SetGCMaxGen0Size(MaxGen0Size);
- }
-
- return (hr);
-}
-
-HRESULT CorGCHost::SetGCStartupLimitsEx(
- SIZE_T SegmentSize,
- SIZE_T MaxGen0Size)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // Set default overrides if specified by caller.
- if (SegmentSize != (SIZE_T) ~0 && SegmentSize > 0)
- {
- hr = _SetGCSegmentSize(SegmentSize);
- }
-
- if (SUCCEEDED(hr) && MaxGen0Size != (SIZE_T) ~0 && MaxGen0Size > 0)
- {
- hr = _SetGCMaxGen0Size(MaxGen0Size);
- }
-
- return (hr);
-}
-
-// Collect the requested generation.
-HRESULT CorGCHost::Collect(
- LONG Generation)
-{
- STATIC_CONTRACT_SO_TOLERANT;
-
- HRESULT hr = E_FAIL;
-
- if (Generation > (int) GCHeapUtilities::GetGCHeap()->GetMaxGeneration())
- hr = E_INVALIDARG;
- else
- {
- // Set up a Thread object if this is called on a native thread.
- Thread *pThread;
- pThread = GetThread();
- if (pThread == NULL)
- pThread = SetupThreadNoThrow(&hr);
-
- if (pThread != NULL)
- {
- // Put thread into co-operative mode, which is how GC must run.
- GCX_COOP();
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
-
- EX_TRY
- {
- hr = GCHeapUtilities::GetGCHeap()->GarbageCollect(Generation);
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- END_SO_INTOLERANT_CODE;
- }
- }
- return (hr);
-}
-
-
-// Return GC counters in the gchost format.
-HRESULT CorGCHost::GetStats(
- COR_GC_STATS *pStats)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
-#if defined(ENABLE_PERF_COUNTERS)
-
- Perf_GC *pgc = &GetPerfCounters().m_GC;
-
- if (!pStats)
- return (E_INVALIDARG);
-
- if (pStats->Flags & COR_GC_COUNTS)
- {
- pStats->ExplicitGCCount = pgc->cInducedGCs;
- for (int idx=0; idx<3; idx++)
- {
- pStats->GenCollectionsTaken[idx] = pgc->cGenCollections[idx];
- }
- }
-
- if (pStats->Flags & COR_GC_MEMORYUSAGE)
- {
- pStats->CommittedKBytes = SizeInKBytes(pgc->cTotalCommittedBytes);
- pStats->ReservedKBytes = SizeInKBytes(pgc->cTotalReservedBytes);
- pStats->Gen0HeapSizeKBytes = SizeInKBytes(pgc->cGenHeapSize[0]);
- pStats->Gen1HeapSizeKBytes = SizeInKBytes(pgc->cGenHeapSize[1]);
- pStats->Gen2HeapSizeKBytes = SizeInKBytes(pgc->cGenHeapSize[2]);
- pStats->LargeObjectHeapSizeKBytes = SizeInKBytes(pgc->cLrgObjSize);
- pStats->KBytesPromotedFromGen0 = SizeInKBytes(pgc->cbPromotedMem[0]);
- pStats->KBytesPromotedFromGen1 = SizeInKBytes(pgc->cbPromotedMem[1]);
- }
- return (S_OK);
-#else
- return (E_NOTIMPL);
-#endif // ENABLE_PERF_COUNTERS
-}
-
-// Return per-thread allocation information.
-HRESULT CorGCHost::GetThreadStats(
- DWORD *pFiberCookie,
- COR_GC_THREAD_STATS *pStats)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- Thread *pThread;
-
- // Get the thread from the caller or the current thread.
- if (!pFiberCookie)
- pThread = GetThread();
- else
- pThread = (Thread *) pFiberCookie;
- if (!pThread)
- return (E_INVALIDARG);
-
- return pThread->GetMemStats (pStats);
-}
-
-// Return per-thread allocation information.
-HRESULT CorGCHost::SetVirtualMemLimit(
- SIZE_T sztMaxVirtualMemMB)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- GCHeapUtilities::GetGCHeap()->SetReservedVMLimit (sztMaxVirtualMemMB);
- return (S_OK);
-}
-#endif // !defined(FEATURE_CORECLR)
+++ /dev/null
-// 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_CAS_POLICY
-
-#include "hostexecutioncontext.h"
-#include "corhost.h"
-#include "security.h"
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-IHostSecurityContext *HostExecutionContextManager::m_pRestrictedHostContext = NULL;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
-// initialize HostRestrictedContext
-void HostExecutionContextManager::InitializeRestrictedContext()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- _ASSERTE(m_pRestrictedHostContext == NULL);
-
- IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
- if (pSM)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pSM->GetSecurityContext(eRestrictedContext, &m_pRestrictedHostContext);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-}
-// notify the Host to SetRestrictedContext
-void HostExecutionContextManager::SetHostRestrictedContext()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if(m_pRestrictedHostContext != NULL)
- {
- IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
- if (pSM)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pSM->SetSecurityContext(eRestrictedContext, m_pRestrictedHostContext);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-}
-
-FCIMPL0(FC_BOOL_RET, HostExecutionContextManager::HostPresent)
-{
- FCALL_CONTRACT;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- FC_RETURN_BOOL(CorHost2::GetHostSecurityManager() != NULL);
-#else // !FEATURE_INCLUDE_ALL_INTERFACES
- FC_RETURN_BOOL(FALSE);
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-}
-FCIMPLEND
-
-FCIMPL1(HRESULT, HostExecutionContextManager::ReleaseSecurityContext, LPVOID handle)
-{
- CONTRACTL {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(handle));
- } CONTRACTL_END;
-
- HELPER_METHOD_FRAME_BEGIN_RET_NOPOLL();
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
- if (pSM)
- {
- // get the IUnknown pointer from handle
- IHostSecurityContext* pSecurityContext = (IHostSecurityContext*)handle;
- // null out the IUnknown pointer in the handle
- //hTokenSAFE->SetHandle((void*)NULL);
- // release the IUnknown pointer if it is non null
- if (pSecurityContext != NULL)
- {
- pSecurityContext->Release();
- }
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- HELPER_METHOD_FRAME_END();
- return S_OK;
-
-}
-FCIMPLEND
-
-FCIMPL1(HRESULT, HostExecutionContextManager::CaptureSecurityContext, SafeHandle* hTokenUNSAFE)
-{
- CONTRACTL {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(hTokenUNSAFE));
- } CONTRACTL_END;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSecurityContext* pCurrentHostSecurityContext = NULL;
- IHostSecurityContext* pCapturedSecurityContext = NULL;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- HRESULT hr = S_OK;
- SAFEHANDLE hTokenSAFE = (SAFEHANDLE) hTokenUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_RET_1(hTokenSAFE);
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
- if (pSM)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pSM->GetSecurityContext(eCurrentContext, &pCurrentHostSecurityContext);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (hr == S_OK)
- {
- if(pCurrentHostSecurityContext != NULL)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pCurrentHostSecurityContext->Capture(&pCapturedSecurityContext);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- hTokenSAFE->SetHandle((void*)pCapturedSecurityContext);
- SafeRelease(pCurrentHostSecurityContext);
- }
- }
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- if (FAILED(hr))
- COMPlusThrowHR(hr);
-
- HELPER_METHOD_FRAME_END();
- return hr;
-
-}
-FCIMPLEND
-
-FCIMPL2(HRESULT, HostExecutionContextManager::CloneSecurityContext, SafeHandle* hTokenUNSAFE, SafeHandle* hTokenClonedUNSAFE)
-{
- CONTRACTL {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(hTokenUNSAFE));
- PRECONDITION(CheckPointer(hTokenClonedUNSAFE));
- } CONTRACTL_END;
-
- SAFEHANDLE hTokenClonedSAFE = (SAFEHANDLE) hTokenClonedUNSAFE;
- SAFEHANDLE hTokenSAFE = (SAFEHANDLE)hTokenUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_2(hTokenSAFE, hTokenClonedSAFE);
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
- if (pSM)
- {
- IHostSecurityContext* pSecurityContext = (IHostSecurityContext*)hTokenSAFE->GetHandle();
- if (pSecurityContext != NULL)
- {
- pSecurityContext->AddRef();
- hTokenClonedSAFE->SetHandle((void*)pSecurityContext);
- }
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- HELPER_METHOD_FRAME_END();
- return S_OK;
-}
-FCIMPLEND
-
-FCIMPL3(HRESULT, HostExecutionContextManager::SetSecurityContext, SafeHandle* hTokenUNSAFE, CLR_BOOL fReturnPrevious, SafeHandle* hTokenPreviousUNSAFE)
-{
- CONTRACTL {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(hTokenUNSAFE));
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- SAFEHANDLE hTokenPreviousSAFE = (SAFEHANDLE) hTokenPreviousUNSAFE;
- SAFEHANDLE hTokenSAFE = (SAFEHANDLE) hTokenUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_2(hTokenSAFE, hTokenPreviousSAFE);
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
- if (pSM)
- {
- if (fReturnPrevious)
- {
- IHostSecurityContext* pPreviousHostSecurityContext = NULL;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pSM->GetSecurityContext(eCurrentContext, &pPreviousHostSecurityContext);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- COMPlusThrowHR(hr);
- // store the previous host context in the safe handle
- hTokenPreviousSAFE->SetHandle((void*)pPreviousHostSecurityContext);
- }
-
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pSM->SetSecurityContext(eCurrentContext, (IHostSecurityContext*)hTokenSAFE->GetHandle());
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- COMPlusThrowHR(hr);
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- HELPER_METHOD_FRAME_END();
- return hr;
-}
-FCIMPLEND
-#endif // #ifdef FEATURE_CAS_POLICY
-
+++ /dev/null
-// 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.
-
-
-
-#ifndef __hostexecutioncontext_h__
-#define __hostexecutioncontext_h__
-
-#ifdef FEATURE_CAS_POLICY
-
-class HostExecutionContextManager
-{
-public:
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- static IHostSecurityContext* m_pRestrictedHostContext;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- static void InitializeRestrictedContext();
- static void SetHostRestrictedContext();
-
- static FCDECL0(FC_BOOL_RET, HostPresent);
- static FCDECL1(HRESULT, ReleaseSecurityContext, LPVOID handle);
- static FCDECL1(HRESULT, CaptureSecurityContext, SafeHandle* hTokenUNSAFE);
- static FCDECL2(HRESULT, CloneSecurityContext, SafeHandle* hTokenUNSAFE, SafeHandle* hTokenClonedUNSAFE);
- static FCDECL3(HRESULT, SetSecurityContext, SafeHandle* hTokenUNSAFE, CLR_BOOL fReturnPrevious, SafeHandle* hTokenPreviousUNSAFE);
-};
-#endif // #ifdef FEATURE_CAS_POLICY
-#endif // __hostexecutioncontext_h__
-
#endif
-#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
-// The helper thread can't call regular new / delete b/c of interop-debugging deadlocks.
-// It must use the (InteropSafe) heap from debugger.h, you also can't allocate normally
-// when we have any other thread hard-suspended.
-
-// Telesto doesn't support interop-debugging, so this won't be an issue.
-
-void AssertAllocationAllowed();
-#endif
HANDLE g_ExecutableHeapHandle = NULL;
return NULL;
#endif
-#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
- AssertAllocationAllowed();
-#endif
#ifdef _DEBUG
if (g_fEEStarted) {
return NULL;
#endif
-#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
- AssertAllocationAllowed();
-#endif
#ifdef FEATURE_INCLUDE_ALL_INTERFACES
IHostMalloc *pHM = CorHost2::GetHostMalloc();
// @todo - Need a backout validation here.
CONTRACT_VIOLATION(SOToleranceViolation);
-#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
- AssertAllocationAllowed();
-#endif
BOOL retVal = FALSE;
STATIC_CONTRACT_NOTHROW;
STATIC_CONTRACT_GC_NOTRIGGER;
-#ifdef FEATURE_CORECLR
#ifndef FEATURE_PAL
UNREACHABLE();
#endif // !FEATURE_PAL
-#else // FEATURE_CORECLR
-
- //
- // Use process executable heap created by the shim
- //
- if (g_ExecutableHeapHandle == NULL)
- {
- extern HANDLE GetProcessExecutableHeap();
- g_ExecutableHeapHandle = GetProcessExecutableHeap();
- }
-
-#endif // FEATURE_CORECLR
// TODO: implement hosted executable heap
return g_ExecutableHeapHandle;
#endif
//***************************************************************************
-#if defined(_DEBUG) && defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
- #define HAS_TRACK_CXX_EXCEPTION_CODE_HACK 1
- #define TRACK_CXX_EXCEPTION_CODE_HACK
-#else
#define HAS_TRACK_CXX_EXCEPTION_CODE_HACK 0
-#endif
#define INITIAL_SUCCESS_COUNT 0x100
EXTERN_C void STDCALL PInvokeStackImbalanceHelper(void);
#endif // MDA_SUPPORTED
-#ifndef FEATURE_CORECLR
-EXTERN_C void STDCALL CopyCtorCallStub(void);
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_STUBS_AS_IL
EXTERN_C void SinglecastDelegateInvokeStub();
}
#endif // FEATURE_CORRUPTING_EXCEPTIONS
-#ifdef FEATURE_CORECLR
// Check if we are dealing with AV or not and if we are,
// ensure that this is a real AV and not managed AV exception
BOOL fIsThrownExceptionAV = FALSE;
EEPOLICY_HANDLE_FATAL_ERROR(COR_E_SECURITY);
}
}
-#endif // FEATURE_CORECLR
// If we're out of memory, then we figure there's probably not memory to maintain a stack trace, so we skip it.
// If we've got a stack overflow, then we figure the stack will be so huge as to make tracking the stack trace
return OVERRIDDEN;
} // ILCriticalHandleMarshaler::ReturnOverride
-#ifndef FEATURE_CORECLR
-//---------------------------------------------------------------------------------------
-//
-MarshalerOverrideStatus ILBlittableValueClassWithCopyCtorMarshaler::ArgumentOverride(NDirectStubLinker* psl,
- BOOL byref,
- BOOL fin,
- BOOL fout,
- BOOL fManagedToNative,
- OverrideProcArgs* pargs,
- UINT* pResID,
- UINT argidx,
- UINT nativeStackOffset)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- ILCodeStream* pslIL = psl->GetMarshalCodeStream();
- ILCodeStream* pslILDispatch = psl->GetDispatchCodeStream();
-
- if (byref)
- {
- *pResID = IDS_EE_BADMARSHAL_COPYCTORRESTRICTION;
- return DISALLOWED;
- }
-
- if (fManagedToNative)
- {
-#ifdef _TARGET_X86_
- _ASSERTE(nativeStackOffset != (UINT)-1);
-
- // get a new copy ctor cookie
- DWORD dwCookieLocalNum = psl->CreateCopyCtorCookie(pslIL);
-
- // and initialize it with our values
- pslIL->EmitLDLOCA(dwCookieLocalNum);
- pslIL->EmitLDARG(argidx);
- pslIL->EmitLDC(nativeStackOffset);
-
- // SetData takes pointers to managed methods although code:CopyCtorCallStubWorker
- // currently calls them via reverse P/Invokes
- if (pargs->mm.m_pCopyCtor)
- {
- pslIL->EmitLDFTN(pslIL->GetToken(pargs->mm.m_pCopyCtor));
- }
- else
- {
- pslIL->EmitLoadNullPtr();
- }
-
- if (pargs->mm.m_pDtor)
- {
- pslIL->EmitLDFTN(pslIL->GetToken(pargs->mm.m_pDtor));
- }
- else
- {
- pslIL->EmitLoadNullPtr();
- }
-
- // <dwCookieLocalNum>.SetData(<argidx>, <nativeStackOffset>, ctorPtr, dtorPtr)
- pslIL->EmitCALL(METHOD__COPYCTORSTUBCOOKIE__SET_DATA, 5, 0);
-
- LocalDesc locDesc(pargs->mm.m_pMT);
- pslIL->SetStubTargetArgType(&locDesc); // native type is the value type
-
- pslILDispatch->EmitLDARG(argidx); // we load the argument directly
- pslILDispatch->EmitLDOBJ(pslILDispatch->GetToken(pargs->mm.m_pMT));
-#else // _TARGET_X86_
- // On WIN64 platforms, copy-constructed arguments are actually passed by reference.
- // This is the same calling convention as used by managed code, but to maintain parity,
- // we mimic the x86 behaviour:
- //
- // 1) create new native value type local
- // 2) run new->CopyCtor(old)
- // 3) run old->Dtor()
-
- LocalDesc locDesc(pargs->mm.m_pMT);
-
- DWORD dwNewValueTypeLocal;
-
- // Step 1
- dwNewValueTypeLocal = pslIL->NewLocal(locDesc);
-
- // Step 2
- if (pargs->mm.m_pCopyCtor)
- {
- pslIL->EmitLDLOCA(dwNewValueTypeLocal);
- pslIL->EmitLDARG(argidx);
- pslIL->EmitCALL(pslIL->GetToken(pargs->mm.m_pCopyCtor), 2, 0);
- }
- else
- {
- pslIL->EmitLDARG(argidx);
- pslIL->EmitLDOBJ(pslIL->GetToken(pargs->mm.m_pMT));
- pslIL->EmitSTLOC(dwNewValueTypeLocal);
- }
-
- // Step 3
- if (pargs->mm.m_pDtor)
- {
- pslIL->EmitLDARG(argidx);
- pslIL->EmitCALL(pslIL->GetToken(pargs->mm.m_pDtor), 1, 0);
- }
-
- pslIL->SetStubTargetArgType(ELEMENT_TYPE_I); // native type is a pointer
- pslILDispatch->EmitLDLOCA(dwNewValueTypeLocal);
-#endif // _TARGET_X86_
-
- return OVERRIDDEN;
- }
- else
- {
- // nothing to do but pass the value along
- // note that on x86 the argument comes by-value but is converted to pointer by the UM thunk
- // so that we don't make copies that would not be accounted for by copy ctors
- LocalDesc locDesc(pargs->mm.m_pMT);
- locDesc.MakeCopyConstructedPointer();
-
- pslIL->SetStubTargetArgType(&locDesc); // native type is a pointer
- pslILDispatch->EmitLDARG(argidx);
-
- return OVERRIDDEN;
- }
-}
-#endif // FEATURE_CORECLR
LocalDesc ILArgIteratorMarshaler::GetNativeType()
{
nativeSize = wNativeSize;
}
-#if defined(_TARGET_X86_) || (defined(_TARGET_AMD64_) && defined(_WIN64) && !defined(FEATURE_CORECLR))
+#if defined(_TARGET_X86_)
// JIT32 and JIT64 (which is only used on the Windows Desktop CLR) has a problem generating
// code for the pinvoke ILStubs which do a return using a struct type. Therefore, we
// change the signature of calli to return void and make the return buffer as first argument.
};
-#ifndef FEATURE_CORECLR
-class ILBlittableValueClassWithCopyCtorMarshaler : public ILMarshaler
-{
-public:
- enum
- {
- c_fInOnly = TRUE,
- c_nativeSize = VARIABLESIZE,
- c_CLRSize = sizeof(OBJECTREF),
- };
-
- LocalDesc GetManagedType()
- {
- LIMITED_METHOD_CONTRACT;
- return LocalDesc();
- }
-
- LocalDesc GetNativeType()
- {
- LIMITED_METHOD_CONTRACT;
- return LocalDesc();
- }
-
- static MarshalerOverrideStatus ArgumentOverride(NDirectStubLinker* psl,
- BOOL byref,
- BOOL fin,
- BOOL fout,
- BOOL fManagedToNative,
- OverrideProcArgs* pargs,
- UINT* pResID,
- UINT argidx,
- UINT nativeStackOffset);
-
-
-};
-#endif // !FEATURE_CORECLR
class ILArgIteratorMarshaler : public ILMarshaler
}
}
-#ifndef FEATURE_CORECLR
- //
- // Publish ETW events for IL stubs
- //
- if (bFireETWCacheHitEvent)
- {
- if (ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, ILStubCacheHit))
- {
-
- SString strNamespaceOrClassName, strMethodName, strMethodSignature;
- UINT64 uModuleId = 0;
-
- if (pTargetMD)
- {
- pTargetMD->GetMethodInfoWithNewSig(strNamespaceOrClassName, strMethodName, strMethodSignature);
- uModuleId = (UINT64)pTargetMD->GetModule()->GetAddrModuleID();
- }
-
- DWORD dwToken = 0;
- if (pTargetMD)
- dwToken = pTargetMD->GetMemberDef();
-
- //
- // Truncate string fields. Make sure the whole event is less than 64KB
- //
- TruncateUnicodeString(strNamespaceOrClassName, ETW_IL_STUB_EVENT_STRING_FIELD_MAXSIZE);
- TruncateUnicodeString(strMethodName, ETW_IL_STUB_EVENT_STRING_FIELD_MAXSIZE);
- TruncateUnicodeString(strMethodSignature, ETW_IL_STUB_EVENT_STRING_FIELD_MAXSIZE);
-
- FireEtwILStubCacheHit(
- GetClrInstanceId(), // ClrInstanceId
- uModuleId, // ModuleIdentifier
- (UINT64)pMD, // StubMethodIdentifier
- dwToken, // ManagedInteropMethodToken
- strNamespaceOrClassName.GetUnicode(), // ManagedInteropMethodNamespace
- strMethodName.GetUnicode(), // ManagedInteropMethodName
- strMethodSignature.GetUnicode() // ManagedInteropMethodSignature
- );
- }
- }
-#endif // !FEATURE_CORECLR
if (!pMD)
{
METHOD__IDISPOSABLE_TO_ICLOSABLE_ADAPTER__CLOSE
};
-#ifdef FEATURE_CORECLR
DEFINE_ASM_QUAL_TYPE_NAME(NCCWINRT_ASM_QUAL_TYPE_NAME, g_INotifyCollectionChanged_WinRTName, g_SystemRuntimeWindowsRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
DEFINE_ASM_QUAL_TYPE_NAME(NCCMA_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedToManagedAdapterName, g_SystemRuntimeWindowsRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
DEFINE_ASM_QUAL_TYPE_NAME(NCCWA_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedToWinRTAdapterName, g_SystemRuntimeWindowsRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
DEFINE_ASM_QUAL_TYPE_NAME(CMDWA_ASM_QUAL_TYPE_NAME, g_ICommandToWinRTAdapterName, g_SystemRuntimeWindowsRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
DEFINE_ASM_QUAL_TYPE_NAME(NCCEHWINRT_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedEventHandler_WinRT, g_SystemRuntimeWindowsRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
DEFINE_ASM_QUAL_TYPE_NAME(PCEHWINRT_ASM_QUAL_TYPE_NAME, g_PropertyChangedEventHandler_WinRT_Name, g_SystemRuntimeWindowsRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-#else
-DEFINE_ASM_QUAL_TYPE_NAME(NCCWINRT_ASM_QUAL_TYPE_NAME, g_INotifyCollectionChanged_WinRTName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(NCCMA_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedToManagedAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(NCCWA_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedToWinRTAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(NPCWINRT_ASM_QUAL_TYPE_NAME, g_INotifyPropertyChanged_WinRTName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(NPCMA_ASM_QUAL_TYPE_NAME, g_NotifyPropertyChangedToManagedAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(NPCWA_ASM_QUAL_TYPE_NAME, g_NotifyPropertyChangedToWinRTAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(CMDWINRT_ASM_QUAL_TYPE_NAME, g_ICommand_WinRTName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(CMDMA_ASM_QUAL_TYPE_NAME, g_ICommandToManagedAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(CMDWA_ASM_QUAL_TYPE_NAME, g_ICommandToWinRTAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(NCCEHWINRT_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedEventHandler_WinRT, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(PCEHWINRT_ASM_QUAL_TYPE_NAME, g_PropertyChangedEventHandler_WinRT_Name, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-
-#endif
const WinRTInterfaceRedirector::NonMscorlibRedirectedInterfaceInfo WinRTInterfaceRedirector::s_rNonMscorlibInterfaceInfos[3] =
{
LPCWSTR pwszClassName = winrtClassName.GetRawBuffer(&cchClassName);
SString ssClassName(SString::Literal, pwszClassName, cchClassName);
-#ifndef FEATURE_CORECLR
- if (ETW_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATE_DYNAMICTYPEUSAGE_KEYWORD))
- {
- FireEtwIInspectableRuntimeClassName(pwszClassName, GetClrInstanceId());
- }
-#endif
// Check a cache to see if this has already been looked up.
AppDomain *pDomain = GetAppDomain();
InvokeUtil::CheckAccessClass(pCtx, pClass, checkAccessForImplicitValueTypeCtor);
-#ifndef FEATURE_CORECLR
- // Reflection invocation should turn critical method access into a full demand of full trust
- // for level 2 assemblies.
- if (InvokeUtil::IsCriticalWithConversionToFullDemand(pClass))
- {
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_FULL_TRUST);
- }
-#endif //FEATURE_CORECLR
}
#ifndef DACCESS_COMPILE
}
CONTRACTL_END;
-#ifndef FEATURE_CORECLR
- // Security checks are expensive as they involve stack walking. Avoid them if we can.
- // In immersive we don't allow private reflection to framework code. So we need to perform
- // the access check even if all the domains on the stack are fully trusted.
- if (Security::AllDomainsOnStackFullyTrusted() && !AppX::IsAppXProcess() && !pParentMT->GetAssembly()->IsDisabledPrivateReflection())
- return;
-#endif // FEATURE_CORECLR
InvokeUtil::CheckAccessMethod(pSCtx,
pParentMT,
pInstanceMT,
pMeth);
-#ifndef FEATURE_CORECLR
- // Reflection invocation should turn critical method access into a full demand of full trust
- // for level 2 assemblies.
- if (fCriticalToFullDemand && InvokeUtil::IsCriticalWithConversionToFullDemand(pMeth, pParentMT))
- {
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_FULL_TRUST);
-
- // No need to do any more checks if a full trust full demand has succeeded.
- return;
- }
-#endif //FEATURE_CORECLR
if (pMeth->RequiresLinktimeCheck())
{
// stack walks in order to close security holes in poorly written
// reflection users.
-#ifdef FEATURE_APTCA
- if (Security::IsUntrustedCallerCheckNeeded(pMeth))
- {
- if (pSCtx->GetCallerMT())
- {
- // Check for untrusted caller
- // It is possible that wrappers like VBHelper libraries that are
- // fully trusted, make calls to public methods that do not have
- // safe for Untrusted caller custom attribute set.
- // Like all other link demand that gets transformed to a full stack
- // walk for reflection, calls to public methods also gets
- // converted to full stack walk
-
- Security::DoUntrustedCallerChecks(
- pSCtx->GetCallerMT()->GetAssembly(), pMeth,
- TRUE);
- }
- }
-#endif // FEATURE_APTCA
struct _gc
{
GCPROTECT_END();
-#ifdef FEATURE_CORECLR
if (pMeth->IsNDirect() ||
(pMeth->IsComPlusCall() && !pMeth->IsInterface()))
{
}
}
-#else // FEATURE_CORECLR
- // We perform automatic linktime checks for UnmanagedCode in three cases:
- // o P/Invoke calls.
- // o Calls through an interface that have a suppress runtime check
- // attribute on them (these are almost certainly interop calls).
- // o Interop calls made through method impls.
- if (pMeth->IsNDirect() ||
- (pMeth->IsInterface() &&
- (pMeth->GetMDImport()->GetCustomAttributeByName(pParentMT->GetCl(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK ||
- pMeth->GetMDImport()->GetCustomAttributeByName(pMeth->GetMemberDef(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK) ) ||
- (pMeth->IsComPlusCall() && !pMeth->IsInterface()))
- {
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_UNMANAGED_CODE);
- }
-#endif // FEATURE_CORECLR
}
// @todo:
}
}
-#ifndef FEATURE_CORECLR
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_SKIP_VER);
-#endif // !FEATURE_CORECLR
}
}
#endif // #ifndef DACCESS_COMPILE
InvokeUtil::CheckAccessField(pCtx, pTargetMT, pInstanceMT, pTargetField);
-#ifndef FEATURE_CORECLR
- // Reflection invocation should turn critical method access into a full demand of full trust
- // for level 2 assemblies.
- if (InvokeUtil::IsCriticalWithConversionToFullDemand(pTargetField, pInstanceMT))
- {
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_FULL_TRUST);
- }
-#endif //FEATURE_CORECLR
}
//
AppDomain * pAppDomain = GetAppDomain();
-#ifdef FEATURE_CORECLR
if (pAppDomain->GetSecurityDescriptor()->IsFullyTrusted())
// Ignore transparency so that reflection invocation is consistenct with LCG.
return AccessCheckOptions::kMemberAccess;
-#else // !FEATURE_CORECLR
- return
- AppX::IsAppXProcess() ?
- (Security::AllDomainsOnStackFullyTrusted() ?
- AccessCheckOptions::kUserCodeOnlyRestrictedMemberAccessNoTransparency :
- AccessCheckOptions::kUserCodeOnlyRestrictedMemberAccess) :
- AccessCheckOptions::kRestrictedMemberAccess;
-#endif //FEATURE_CORECLR
}
#endif // CROSSGEN_COMPILE
#include "gccover.h"
#endif // HAVE_GCCOVER
-#ifdef FEATURE_CORECLR
#include "runtimehandles.h"
-#endif
//========================================================================
//
{
FCALL_CONTRACT;
-#ifdef FEATURE_CORECLR
// If we're in full trust, then we don't enforce the delegate binding rules
if (GetAppDomain()->GetSecurityDescriptor()->IsFullyTrusted())
{
return;
}
-#endif // FEATURE_CORECLR
// Tailcall to the real implementation
ENDFORBIDGC();
HELPER_METHOD_FRAME_BEGIN_NOPOLL();
{
-#ifdef FEATURE_CORECLR
// Transparent methods that contains unverifiable code is not allowed.
MethodDesc *pMethod = GetMethod(methHnd_);
SecurityTransparent::ThrowMethodAccessException(pMethod);
-#else // FEATURE_CORECLR
- //
- // inject a full-demand for unmanaged code permission at runtime
- // around methods in transparent assembly that contains unverifiable code
- Security::SpecialDemand(SSWT_DECLARATIVE_DEMAND, SECURITY_UNMANAGED_CODE);
-#endif // FEATURE_CORECLR
}
HELPER_METHOD_FRAME_END_POLL();
}
{
*pAccessCheckType = AccessCheckOptions::kRestrictedMemberAccess;
-#ifdef FEATURE_CORECLR
// For compatibility, don't do transparency checks from dynamic methods in FT CoreCLR.
if (GetAppDomain()->GetSecurityDescriptor()->IsFullyTrusted())
*pAccessCheckType = AccessCheckOptions::kRestrictedMemberAccessNoTransparency;
-#endif // FEATURE_CORECLR
#ifdef FEATURE_COMPRESSEDSTACK
if (dwSecurityFlags & DynamicResolver::HasCreationContext)
}
else
{
-#ifdef FEATURE_CORECLR
// For compatibility, don't do transparency checks from dynamic methods in FT CoreCLR.
if (GetAppDomain()->GetSecurityDescriptor()->IsFullyTrusted())
*pAccessCheckType = AccessCheckOptions::kNormalAccessNoTransparency;
-#endif // FEATURE_CORECLR
}
return doAccessCheck;
IfFailThrow(sig.GetCallingConvInfo(&data));
sigRet->callConv = (CorInfoCallConv) data;
-#if defined(FEATURE_CORECLR)
if ((isCallConv(sigRet->callConv, IMAGE_CEE_CS_CALLCONV_VARARG)) ||
(isCallConv(sigRet->callConv, IMAGE_CEE_CS_CALLCONV_NATIVEVARARG)))
{
// This signature corresponds to a method that uses varargs, which are not supported.
COMPlusThrow(kInvalidProgramException, IDS_EE_VARARG_NOT_SUPPORTED);
}
-#endif // FEATURE_CORECLR
// Skip number of type arguments
if (sigRet->callConv & IMAGE_CEE_CS_CALLCONV_GENERIC)
//This just throws.
if (pCalleeForSecurity->RequiresLinktimeCheck())
{
-#ifdef FEATURE_CORECLR
//hostProtectionAttribute(HPA) can be removed for coreclr mscorlib.dll
//So if the call to LinktimeCheckMethod() is only b'coz of HPA then skip it
if (!pCalleeForSecurity->RequiresLinkTimeCheckHostProtectionOnly())
-#endif
Security::LinktimeCheckMethod(pCallerForSecurity->GetAssembly(), pCalleeForSecurity);
}
pCalleeForSecurity,
NULL,
accessCheckOptions,
-#ifdef FEATURE_CORECLR
FALSE,
-#else
- TRUE,
-#endif //FEATURE_CORECLR
TRUE
);
{
BOOL fNeedsTransparencyCheck = TRUE;
-#ifdef FEATURE_CORECLR
// All LCG methods are transparent in CoreCLR. When we switch from PT
// to FT most user assemblies will become opportunistically critical.
// If a LCG method calls a method in such an assembly it will stop working.
// See also AccessCheckOptions::DemandMemberAccess.
if (GetAppDomain()->GetSecurityDescriptor()->IsFullyTrusted() && pCallerForSecurity->IsLCGMethod())
fNeedsTransparencyCheck = FALSE;
-#endif // FEATURE_CORECLR
if (fNeedsTransparencyCheck)
{
doCheck = ModifyCheckForDynamicMethod(GetMethod(hCaller)->AsDynamicMethodDesc()->GetResolver(),
&accessingType, &accessCheckOptions, &pIgnored);
if (accessCheckOptions == AccessCheckOptions::kRestrictedMemberAccess
-#ifdef FEATURE_CORECLR
|| accessCheckOptions == AccessCheckOptions::kRestrictedMemberAccessNoTransparency
-#endif //FEATURE_CORECLR
)
doCheck = FALSE;
}
pEEInfoOut->osPageSize = OS_PAGE_SIZE;
pEEInfoOut->maxUncheckedOffsetForNullObject = MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT;
-#if defined(FEATURE_CORECLR)
pEEInfoOut->targetAbi = CORINFO_CORECLR_ABI;
-#else
- pEEInfoOut->targetAbi = CORINFO_DESKTOP_ABI;
-#endif
OSVERSIONINFO sVerInfo;
sVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
CorJitResult ret = CORJIT_SKIPPED; // Note that CORJIT_SKIPPED is an error exit status code
-#if !defined(FEATURE_CORECLR)
- // Ask the JIT to generate desktop-quirk-compatible code.
- jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DESKTOP_QUIRKS);
-#endif
comp->setJitFlags(jitFlags);
BEGIN_SO_TOLERANT_CODE(GetThread());
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- ret = getJit()->compileMethod( comp,
- info,
- CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS,
- nativeEntry,
- nativeSizeOfCode);
-
-#else // defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
#if defined(ALLOW_SXS_JIT) && !defined(CROSSGEN_COMPILE)
if (FAILED(ret) && jitMgr->m_alternateJit
}
#endif // !defined(CROSSGEN_COMPILE)
-#endif // defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
#if defined(FEATURE_GDBJIT)
if (SUCCEEDED(ret) && *nativeEntry != NULL)
{
STANDARD_VM_CONTRACT;
-#ifdef FEATURE_CORECLR
//Right now if we don't have a debug interface on CoreCLR, we can't generate debug info. So, in those
//cases don't attempt it.
if (!g_pDebugInterface)
return flags;
-#endif //FEATURE_CORECLR
#ifdef DEBUGGING_SUPPORTED
void STDCALL JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle);
};
-#ifndef FEATURE_CORECLR
-//
-// Obfluscators that are hacking into the JIT expect certain methods to exist in certain places of CEEInfo vtable. Add artifical slots
-// to the vtable to avoid breaking apps by .NET 4.5 in-place update.
-//
-
-class ICorMethodInfo_Hack
-{
-public:
- virtual const char* __stdcall ICorMethodInfo_Hack_getMethodName (CORINFO_METHOD_HANDLE ftnHnd, const char** scopeName) = 0;
-};
-
-class ICorModuleInfo_Hack
-{
-public:
- virtual void ICorModuleInfo_Hack_dummy() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
-};
-
-class ICorClassInfo_Hack
-{
-public:
- virtual void ICorClassInfo_Hack_dummy1() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy2() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy3() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy4() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy5() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy6() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy7() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy8() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy9() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy10() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy11() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy12() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy13() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy14() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
-
- virtual mdMethodDef __stdcall ICorClassInfo_Hack_getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod) = 0;
-};
-
-class ICorStaticInfo_Hack : public virtual ICorMethodInfo_Hack, public virtual ICorModuleInfo_Hack, public virtual ICorClassInfo_Hack
-{
- virtual void ICorStaticInfo_Hack_dummy() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
-};
-
-#endif // FEATURE_CORECLR
/*********************************************************************/
/*********************************************************************/
class CEEInfo : public ICorJitInfo
-#ifndef FEATURE_CORECLR
- , public virtual ICorStaticInfo_Hack
-#endif
{
friend class CEEDynamicCodeInfo;
DEFINE_METASIG_T(SM(RealProxy_Class_RetBool, C(REAL_PROXY) C(CLASS), F))
#endif
-#ifndef FEATURE_CORECLR
-DEFINE_METASIG_T(SM(ExecutionContext_ContextCallback_Object_Bool_RetVoid, \
- C(EXECUTIONCONTEXT) C(CONTEXTCALLBACK) j F, v))
-#endif
#if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
DEFINE_METASIG_T(SM(SecurityContext_ContextCallback_Object_RetVoid, \
C(SECURITYCONTEXT) C(CONTEXTCALLBACK) j, v))
DEFINE_METASIG(SM(ArrByte_ArrByte_RefObj_RetObj, a(b) a(b) r(j), j))
DEFINE_METASIG_T(SM(PtrSByt_Int_Int_Encoding_RetStr, P(B) i i C(ENCODING), s))
DEFINE_METASIG_T(SM(Evidence_RetEvidence, C(EVIDENCE), C(EVIDENCE)))
-#ifdef FEATURE_CAS_POLICY
-DEFINE_METASIG_T(SM(PEFile_Evidence_RetEvidence, C(SAFE_PEFILE_HANDLE) C(EVIDENCE), C(EVIDENCE)))
-#endif // FEATURE_CAS_POLICY
DEFINE_METASIG_T(SM(Evidence_Asm_RetEvidence, C(EVIDENCE) C(ASSEMBLY), C(EVIDENCE)))
DEFINE_METASIG_T(IM(Evidence_RetVoid, C(EVIDENCE), v))
DEFINE_METASIG(IM(RetArrByte, _, a(b)))
DEFINE_METASIG_T(IM(RetArrParameterInfo, _, a(C(PARAMETER))))
DEFINE_METASIG_T(IM(RetCultureInfo, _, C(CULTURE_INFO)))
-#ifdef FEATURE_CAS_POLICY
-DEFINE_METASIG_T(IM(RetSecurityElement, _, C(SECURITY_ELEMENT)))
-#endif // FEATURE_CAS_POLICY
DEFINE_METASIG_T(SM(RetThread, _, C(THREAD)))
DEFINE_METASIG_T(SM(Str_Evidence_Str_Str_Bool_RetAppDomain, s C(EVIDENCE) s s F, C(APP_DOMAIN)))
DEFINE_METASIG_T(SM(Str_RetAppDomain, s, C(APP_DOMAIN)))
DEFINE_METASIG_T(SM(Str_AppDomainSetup_Evidence_Evidence_IntPtr_Str_ArrStr_ArrStr_RetObj, s C(APPDOMAIN_SETUP) C(EVIDENCE) C(EVIDENCE) I s a(s) a(s), j))
-#ifdef FEATURE_APTCA
-DEFINE_METASIG(IM(PtrChar_Int_PtrByte_Int_RetBool, P(u) i P(b) i, F))
-#endif //FEATURE_APTCA
#ifdef FEATURE_COMINTEROP
// System.AppDomain.OnReflectionOnlyNamespaceResolveEvent
DEFINE_METASIG_T(IM(Assembly_Str_RetArrAssembly, C(ASSEMBLY) s, a(C(ASSEMBLY))))
#include "jitinterface.h"
#include "runtimehandles.h"
#include "eventtrace.h"
-#ifndef FEATURE_CORECLR
-#include "fxretarget.h"
-#endif
#include "interoputil.h"
#include "prettyprintsig.h"
#include "formattype.h"
DWORD nbytes = (DWORD)(strlen(GetEntrypointName()) + 1);
szAnsiEntrypointName[nbytes] = '\0'; // Add an extra '\0'.
-#if !defined(FEATURE_CORECLR) && defined(_WIN64)
- //
- // Forward {Get|Set}{Window|Class}Long to their corresponding Ptr version
- //
-
- // LONG SetWindowLong( HWND hWnd, int nIndex, LONG dwNewLong);
- // LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong);
- //
- // LONG GetWindowLong( HWND hWnd, int nIndex);
- // LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex);
- //
- // DWORD GetClassLong( HWND hWnd, int nIndex);
- // ULONG_PTR GetClassLongPtr( HWND hWnd, int nIndex);
- //
- // DWORD SetClassLong( HWND hWnd, int nIndex, LONG dwNewLong);
- // ULONG_PTR SetClassLongPtr( HWND hWnd, int nIndex, LONG_PTR dwNewLong);
-
- if (!SString::_stricmp(GetEntrypointName(), "SetWindowLong") ||
- !SString::_stricmp(GetEntrypointName(), "GetWindowLong") ||
- !SString::_stricmp(GetEntrypointName(), "SetClassLong") ||
- !SString::_stricmp(GetEntrypointName(), "GetClassLong"))
- {
- szAnsiEntrypointName[nbytes-1] = 'P';
- szAnsiEntrypointName[nbytes+0] = 't';
- szAnsiEntrypointName[nbytes+1] = 'r';
- szAnsiEntrypointName[nbytes+2] = '\0';
- szAnsiEntrypointName[nbytes+3] = '\0';
- nbytes += 3;
- }
-#endif // !FEATURE_CORECLR && _WIN64
// If the program wants the ANSI api or if Unicode APIs are unavailable.
if (IsNativeAnsi())
if (!pFunc)
{
-#if !defined(FEATURE_CORECLR)
- if (hMod == CLRGetModuleHandle(W("kernel32.dll")))
- {
- szAnsiEntrypointName[nbytes-1] = '\0';
- if (0==strcmp(szAnsiEntrypointName, "MoveMemory") ||
- 0==strcmp(szAnsiEntrypointName, "CopyMemory"))
- {
- pFunc = GetProcAddress(hMod, funcName = "RtlMoveMemory");
- }
- else if (0==strcmp(szAnsiEntrypointName, funcName = "FillMemory"))
- {
- pFunc = GetProcAddress(hMod, funcName = "RtlFillMemory");
- }
- else if (0==strcmp(szAnsiEntrypointName, funcName = "ZeroMemory"))
- {
- pFunc = GetProcAddress(hMod, funcName = "RtlZeroMemory");
- }
- }
-#endif // !FEATURE_CORECLR
#if defined(_TARGET_X86_)
/* try mangled names only for __stdcalls */
}
CONTRACTL_END;
-#ifndef FEATURE_CORECLR
- // We only care about this bit for NDirect and ComPlusCall
- if (!IsNDirect() && !IsComPlusCall())
- return;
-
- BOOL hasAttr = FALSE;
- HRESULT hr = pImport->GetCustomAttributeByName(GetMemberDef(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL);
- IfFailThrow(hr);
- hasAttr = (hr == S_OK);
-
-
- if (IsNDirect())
- ((NDirectMethodDesc*)this)->SetSuppressUnmanagedCodeAccessAttr(hasAttr);
-
-#ifdef FEATURE_COMINTEROP
- if (IsComPlusCall())
- ((ComPlusCallMethodDesc*)this)->SetSuppressUnmanagedCodeAccessAttr(hasAttr);
-#endif
-
-#endif // FEATURE_COMINTEROP
}
//*******************************************************************************
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
HRESULT hr = GetMDImport()->GetCustomAttributeByName(GetMemberDef(),
g_NativeCallableAttribute,
NULL,
{
return TRUE;
}
-#endif //FEATURE_CORECLR
return FALSE;
}
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return TRUE;
-#else // FEATURE_CORECLR
-
- // In AppX processes, there is only one full trust AppDomain, so there is never any need to do a security
- // callout on interop stubs
- if (AppX::IsAppXProcess())
- {
- return TRUE;
- }
-
- if (IsNDirect())
- return ((NDirectMethodDesc*)this)->HasSuppressUnmanagedCodeAccessAttr();
-#ifdef FEATURE_COMINTEROP
- else if (IsComPlusCall())
- return ((ComPlusCallMethodDesc*)this)->HasSuppressUnmanagedCodeAccessAttr();
-#endif // FEATURE_COMINTEROP
- else
- return FALSE;
-
-#endif // FEATURE_CORECLR
}
#ifdef FEATURE_COMINTEROP
return (ndirect.m_wFlags & kNativeNoMangle) != 0;
}
-#ifndef FEATURE_CORECLR
- BOOL HasSuppressUnmanagedCodeAccessAttr() const
- {
- LIMITED_METHOD_CONTRACT;
-
- return (ndirect.m_wFlags & kHasSuppressUnmanagedCodeAccess) != 0;
- }
-
- void SetSuppressUnmanagedCodeAccessAttr(BOOL value)
- {
- LIMITED_METHOD_CONTRACT;
-
- if (value)
- ndirect.m_wFlags |= kHasSuppressUnmanagedCodeAccess;
- }
-#endif
DWORD GetECallID() const
{
return m_pComPlusCallInfo->m_pEventProviderMD;
}
-#ifndef FEATURE_CORECLR
-
- BOOL HasSuppressUnmanagedCodeAccessAttr()
- {
- LIMITED_METHOD_CONTRACT;
-
- if (m_pComPlusCallInfo != NULL)
- {
- return (m_pComPlusCallInfo->m_flags & ComPlusCallInfo::kHasSuppressUnmanagedCodeAccess) != 0;
- }
-
- // it is possible that somebody will call this before we initialized m_pComPlusCallInfo
- return (GetMDImport()->GetCustomAttributeByName(GetMemberDef(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK);
- }
-
- void SetSuppressUnmanagedCodeAccessAttr(BOOL value)
- {
- LIMITED_METHOD_CONTRACT;
-
- if (value)
- FastInterlockOr(reinterpret_cast<DWORD *>(&m_pComPlusCallInfo->m_flags), ComPlusCallInfo::kHasSuppressUnmanagedCodeAccess);
- }
-#endif // FEATURE_CORECLR
BOOL RequiresArgumentWrapping()
{
#include "zapsig.h"
#endif //FEATURE_PREJIT
-#include "hostexecutioncontext.h"
-
#ifdef FEATURE_COMINTEROP
#include "comcallablewrapper.h"
#include "clrtocomcall.h"
return;
}
-#ifdef FEATURE_CAS_POLICY
- // Notify the host to setup the restricted context before finalizing each object
- HostExecutionContextManager::SetHostRestrictedContext();
-#endif // FEATURE_CAS_POLICY
// Determine if the object has a critical or normal finalizer.
BOOL fCriticalFinalizer = pMT->HasCriticalFinalizer();
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return false;
-#else
- // all WinRT types have an imaginary [SuppressUnmanagedCodeSecurity] attribute on them
- if (IsProjectedFromWinRT())
- return false;
-
- // In AppX processes, there is only one full trust AppDomain, so there is never any need to do a security
- // callout on interop stubs
- if (AppX::IsAppXProcess())
- return false;
-
- return GetMDImport()->GetCustomAttributeByName(GetCl(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_FALSE;
-#endif // FEATURE_CORECLR
}
#endif // !DACCESS_COMPILE
inline BOOL MethodTable::SupportsAutoNGen()
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- return GetAssembly()->SupportsAutoNGen();
-#else
return FALSE;
-#endif
}
//==========================================================================================
inline BOOL MethodTable::RunCCTorAsIfNGenImageExists()
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- return this->SupportsAutoNGen();
-#else
#ifdef FEATURE_CORESYSTEM
return TRUE; // On our coresystem builds we will always be using triton in the customer scenario.
#else
return FALSE;
#endif
-#endif
}
//==========================================================================================
DEFINE_ASM_QUAL_TYPE_NAME(URI_ASM_QUAL_TYPE_NAME, g_SystemUriClassName, g_SystemRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_FXKeyToken);
DEFINE_ASM_QUAL_TYPE_NAME(NCCEVENTARGS_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedEventArgsName, g_ObjectModelAsmName, VER_ASSEMBLYVERSION_STR, g_FXKeyToken);
-#ifdef FEATURE_CORECLR
DEFINE_ASM_QUAL_TYPE_NAME(NCCEVENTARGS_MARSHALER_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedEventArgsMarshalerName, g_SystemRuntimeWindowsRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-#else
- DEFINE_ASM_QUAL_TYPE_NAME(NCCEVENTARGS_MARSHALER_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedEventArgsMarshalerName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-#endif
DEFINE_ASM_QUAL_TYPE_NAME(PCEVENTARGS_ASM_QUAL_TYPE_NAME, g_PropertyChangedEventArgsName, g_ObjectModelAsmName, VER_ASSEMBLYVERSION_STR, g_FXKeyToken);
-#ifdef FEATURE_CORECLR
DEFINE_ASM_QUAL_TYPE_NAME(PCEVENTARGS_MARSHALER_ASM_QUAL_TYPE_NAME, g_PropertyChangedEventArgsMarshalerName, g_SystemRuntimeWindowsRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-#else
- DEFINE_ASM_QUAL_TYPE_NAME(PCEVENTARGS_MARSHALER_ASM_QUAL_TYPE_NAME, g_PropertyChangedEventArgsMarshalerName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-#endif
#define OLECOLOR_TO_SYSTEMCOLOR_METH_NAME "FromOle"
CorNativeType nativeType = NATIVE_TYPE_DEFAULT;
Assembly *pAssembly = pModule->GetAssembly();
-#ifndef FEATURE_CORECLR
- BOOL fNeedsCopyCtor = FALSE;
-#endif // !FEATURE_CORECLR
m_BestFit = BestFit;
m_ThrowOnUnmappableChar = ThrowOnUnmappableChar;
m_ms = ms;
IfFailGoto(sig.GetElemType(NULL), lFail);
mtype = sig.PeekElemTypeNormalized(pModule, pTypeContext);
-#ifndef FEATURE_CORECLR // no copy ctor support in CoreCLR
- // Check for Copy Constructor Modifier - peek closed elem type here to prevent ELEMENT_TYPE_VALUETYPE
- // turning into a primitive.
- if (sig.PeekElemTypeClosed(pModule, pTypeContext) == ELEMENT_TYPE_VALUETYPE)
- {
- // Skip ET_BYREF
- IfFailGoto(sigtmp.GetByte(NULL), lFail);
-
- if (sigtmp.HasCustomModifier(pModule, "Microsoft.VisualC.NeedsCopyConstructorModifier", ELEMENT_TYPE_CMOD_REQD) ||
- sigtmp.HasCustomModifier(pModule, "System.Runtime.CompilerServices.IsCopyConstructed", ELEMENT_TYPE_CMOD_REQD) )
- {
- mtype = ELEMENT_TYPE_VALUETYPE;
- fNeedsCopyCtor = TRUE;
- m_byref = FALSE;
- }
- }
-#endif // !FEATURE_CORECLR
}
else
{
IfFailGoto(E_FAIL, lFail);
}
-#ifndef FEATURE_CORECLR
- // Check for Copy Constructor Modifier
- if (sigtmp.HasCustomModifier(pModule, "Microsoft.VisualC.NeedsCopyConstructorModifier", ELEMENT_TYPE_CMOD_REQD) ||
- sigtmp.HasCustomModifier(pModule, "System.Runtime.CompilerServices.IsCopyConstructed", ELEMENT_TYPE_CMOD_REQD) )
- {
- mtype = mtype2;
-
- // Keep the sig pointer in sync with mtype (skip ELEMENT_TYPE_PTR) because for the rest
- // of this method we are pretending that the parameter is a value type passed by-value.
- IfFailGoto(sig.GetElemType(NULL), lFail);
-
- fNeedsCopyCtor = TRUE;
- m_byref = FALSE;
- }
-#endif // !FEATURE_CORECLR
}
}
else
}
else
{
-#ifndef FEATURE_CORECLR
- if (fNeedsCopyCtor)
- {
- if (m_ms == MARSHAL_SCENARIO_WINRT)
- {
- // our WinRT-optimized GetCOMIPFromRCW helpers don't support copy
- // constructor stubs so make sure that this marshaler will not be used
- m_resID = IDS_EE_BADMARSHAL_WINRT_COPYCTOR;
- IfFailGoto(E_FAIL, lFail);
- }
-
- MethodDesc *pCopyCtor;
- MethodDesc *pDtor;
- FindCopyCtor(pModule, m_pMT, &pCopyCtor);
- FindDtor(pModule, m_pMT, &pDtor);
-
- m_args.mm.m_pMT = m_pMT;
- m_args.mm.m_pCopyCtor = pCopyCtor;
- m_args.mm.m_pDtor = pDtor;
- m_type = MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR;
- }
- else
-#endif // !FEATURE_CORECLR
#ifdef _TARGET_X86_
// JIT64 is not aware of normalized value types and this optimization
// (returning small value types by value in registers) is already done in JIT64.
lExit:
#ifdef FEATURE_COMINTEROP
-#ifdef FEATURE_CORECLR
//Field scenario is not blocked here because we don't want to block loading structs that
//have the types which we are blocking, but never pass it to Interop.
COMPlusThrow(kPlatformNotSupportedException, m_resID);
}
-#endif // FEATURE_CORECLR
if (IsWinRTScenario() && !IsSupportedForWinRT(m_type))
{
{
case MARSHAL_TYPE_BLITTABLEVALUECLASS:
case MARSHAL_TYPE_VALUECLASS:
-#ifndef FEATURE_CORECLR
- case MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR:
-#endif // !FEATURE_CORECLR
return (UINT16) m_pMT->GetNativeSize();
default:
case MARSHAL_TYPE_BLITTABLEVALUECLASS:
case MARSHAL_TYPE_BLITTABLEPTR:
case MARSHAL_TYPE_LAYOUTCLASSPTR:
-#ifndef FEATURE_CORECLR
- case MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR:
-#endif
pDispParamMarshaler = new DispParamRecordMarshaler(m_pMT);
break;
case MARSHAL_TYPE_ARGITERATOR:
strRetVal = W("ArgIterator");
break;
-#ifndef FEATURE_CORECLR
- case MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR:
- strRetVal = W("blittable value class with copy constructor");
- break;
-#endif // FEATURE_CORECLR
#ifdef FEATURE_COMINTEROP
case MARSHAL_TYPE_OBJECT:
strRetVal = W("VARIANT");
}
}
-#ifdef FEATURE_CORECLR
// Avoid throwing exceptions for any managed structs that have layouts and have types of fields that gets default to those banned types by default
// We don't know if they will be passed to native code anyway, and the right place to make the check is in the marshallers
if (AppX::IsAppXProcess() && ms != MarshalInfo::MARSHAL_SCENARIO_FIELD)
if (set_error)
COMPlusThrow(kPlatformNotSupportedException, m_resID);
}
-#endif // FEATURE_CORECLR
// If we are exporting, we need to substitute the VTHACK_* VARTYPE with the actual
// types as expressed in the type library.
return m_pWinRTPCEventArgsToSystemPCEventArgsMD;
}
-#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
- BOOL IsEventArgsHelperMethod(MethodDesc *pMD)
- {
- LIMITED_METHOD_CONTRACT;
- return (pMD == m_pSystemNCCEventArgsToWinRTNCCEventArgsMD || pMD == m_pWinRTNCCEventArgsToSystemNCCEventArgsMD ||
- pMD == m_pSystemPCEventArgsToWinRTPCEventArgsMD || pMD == m_pWinRTPCEventArgsToSystemPCEventArgsMD);
- }
-#endif // #if defined(_DEBUG) && !defined(FEATURE_CORECLR)
private:
TypeHandle m_hndSystemNCCEventArgsType;
return m_SystemUriOriginalStringGetterMD;
}
-#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
- BOOL IsUriHelperMethod(MethodDesc *pMD)
- {
- LIMITED_METHOD_CONTRACT;
- return pMD == m_SystemUriCtorMD || pMD == m_SystemUriOriginalStringGetterMD;
- }
-#endif // #if defined(_DEBUG) && !defined(FEATURE_CORECLR)
private:
TypeHandle m_hndSystemUriType;
return m_SystemColorToOleColorMD;
}
-#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
- BOOL IsOleColorHelperMethod(MethodDesc *pMD)
- {
- LIMITED_METHOD_CONTRACT;
- return pMD == m_OleColorToSystemColorMD || pMD == m_SystemColorToOleColorMD;
- }
-#endif // #if defined(_DEBUG) && !defined(FEATURE_CORECLR)
private:
TypeHandle m_hndColorType;
UriMarshalingInfo *GetUriMarshalingInfo();
EventArgsMarshalingInfo *GetEventArgsMarshalingInfo();
-#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
- BOOL IsOleColorHelperMethod(MethodDesc *pMD)
- {
- LIMITED_METHOD_CONTRACT;
- return m_pOleColorInfo != NULL && m_pOleColorInfo->IsOleColorHelperMethod(pMD);
- }
-
- BOOL IsUriHelperMethod(MethodDesc *pMD)
- {
- LIMITED_METHOD_CONTRACT;
- return m_pUriInfo != NULL && m_pUriInfo->IsUriHelperMethod(pMD);
- }
-
- BOOL IsEventArgsHelperMethod(MethodDesc *pMD)
- {
- LIMITED_METHOD_CONTRACT;
- return m_pEventArgsInfo != NULL && m_pEventArgsInfo->IsEventArgsHelperMethod(pMD);
- }
-#endif // #if defined(_DEBUG) && !defined(FEATURE_CORECLR)
#endif // FEATURE_COMINTEROP
#include "currency.h"
#include "comdatetime.h"
#include "comisolatedstorage.h"
-#include "securityconfig.h"
#include "number.h"
#include "compatibilityswitch.h"
#ifdef FEATURE_REMOTING
#include "stubhelpers.h"
#include "ilmarshalers.h"
-#include "hostexecutioncontext.h"
-
#ifdef FEATURE_MULTICOREJIT
#include "multicorejit.h"
#endif
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_LPSTR_BUFFER, CSTRBufferMarshaler, false)
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_UTF8_BUFFER, UTF8BufferMarshaler, false)
-#if defined(FEATURE_COMINTEROP) || !defined(FEATURE_CORECLR)
+#if defined(FEATURE_COMINTEROP)
// CoreCLR doesn't have any support for marshalling interface pointers.
// Not even support for fake CCWs.
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_INTERFACE, InterfaceMarshaler, true)
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_REFERENCECUSTOMMARSHALER, ReferenceCustomMarshaler, false)
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_ARGITERATOR, ArgIteratorMarshaler, false)
-#ifndef FEATURE_CORECLR
-DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR, BlittableValueClassWithCopyCtorMarshaler, false)
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_COMINTEROP
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_OBJECT, ObjectMarshaler, false)
wLoadLevel = 0;
// Extra data
lenModuleName = (unsigned short) lenName;
-#if defined(FEATURE_CORECLR)
lenAssemblyName = (unsigned short) lenAsmName;
recordID += RoundUp(lenModuleName) + RoundUp(lenAssemblyName);
-#else
- recordID += RoundUp(lenModuleName);
-#endif
}
unsigned lenModuleName = (unsigned) strlen(pModuleName);
simpleName.Set((const BYTE *) pModuleName, lenModuleName); // SBuffer::Set copies over name
-#if defined(FEATURE_CORECLR)
SString sAssemblyName;
StackScratchBuffer scratch;
pMod->GetAssembly()->GetManifestFile()->GetDisplayName(sAssemblyName);
LPCUTF8 pAssemblyName = sAssemblyName.GetUTF8(scratch);
unsigned lenAssemblyName = sAssemblyName.GetCount();
assemblyName.Set((const BYTE *) pAssemblyName, lenAssemblyName);
-#endif
#if defined(FEATURE_APPX_BINDER)
const void * pModuleName = module.simpleName;
unsigned lenModuleName = module.simpleName.GetSize();
-#if defined(FEATURE_CORECLR)
const void * pAssemblyName = module.assemblyName;
unsigned lenAssemblyName = module.assemblyName.GetSize();
-#else
- unsigned lenAssemblyName = 0;
-#endif
ModuleRecord mod(lenModuleName, lenAssemblyName);
{
hr = WriteString(pModuleName, lenModuleName, pStream);
-#if defined(FEATURE_CORECLR)
if (SUCCEEDED(hr))
{
hr = WriteString(pAssemblyName, lenAssemblyName, pStream);
}
-#endif
}
return hr;
while (appIt.Next(pDomainAssembly.This()) && SUCCEEDED(hr))
{
-#if !defined(FEATURE_CORECLR)
- if (! pDomainAssembly->IsSystem())
-#endif
{
hr = HandleAssembly(pDomainAssembly);
}
// When running under Appx or CoreCLR for K, AppDomain is normally not shut down properly (CLR in hybrid case, or Alt-F4 shutdown),
// So we only allow writing out after profileWriteTimeout seconds
-#if !defined(FEATURE_CORECLR)
- if (m_fAppxMode)
-#endif
{
// Get the timeout in seconds.
int profileWriteTimeout = (int)CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MultiCoreJitProfileWriteDelay);
NewHolder<MulticoreJitProfilePlayer> player(new (nothrow) MulticoreJitProfilePlayer(
m_pDomain,
-#if defined(FEATURE_CORECLR)
m_pBinderContext,
-#else
- NULL,
-#endif
nSession,
m_fAppxMode));
{
MulticoreJitRecorder * pRecorder = new (nothrow) MulticoreJitRecorder(
pDomain,
-#if defined(FEATURE_CORECLR)
pBinderContext,
-#else
- NULL,
-#endif
m_fAppxMode);
if (pRecorder != NULL)
STANDARD_VM_CONTRACT;
-#if defined(FEATURE_APPX_BINDER) && !defined(FEATURE_CORECLR)
- // When running under Appx, allow framework assembly / first party winmd to load
- // load-level change not allowed in the background thread, unless for resource DLL (loaded for exception throwing), but this could still happen.
- _ASSERTE(! GetThread()->HasThreadStateNC(Thread::TSNC_CallingManagedCodeDisabled) || ModuleHasNoCode(pModule)
- || m_fAppxMode && IsLoadOkay(pModule));
-
-#elif !defined(FEATURE_CORECLR)
-
- _ASSERTE(! GetThread()->HasThreadStateNC(Thread::TSNC_CallingManagedCodeDisabled) || ModuleHasNoCode(pModule));
-
-#endif
if (m_fRecorderActive)
{
unsigned short flags;
unsigned short wLoadLevel;
unsigned short lenModuleName;
-#if defined(FEATURE_CORECLR)
unsigned short lenAssemblyName;
-#endif
ModuleRecord(unsigned lenName = 0, unsigned lenAssemblyName = 0);
return (const char *) (this + 1); // after this record
}
-#if defined(FEATURE_CORECLR)
unsigned AssemblyNameLen() const
{
LIMITED_METHOD_CONTRACT;
{
return GetModuleName() + RoundUp(lenModuleName); // after the module name
}
-#endif
void SetLoadLevel(FileLoadLevel loadLevel)
{
private:
ADID m_DomainID;
-#if defined(FEATURE_CORECLR)
ICLRPrivBinder * m_pBinderContext;
-#endif
LONG m_nMySession;
unsigned m_nStartTime;
BYTE * m_pFileBuffer;
HRESULT ReadCheckFile(const wchar_t * pFileName);
-#if defined(FEATURE_CORECLR)
DomainAssembly * LoadAssembly(SString & assemblyName);
-#endif
public:
{
private:
AppDomain * m_pDomain; // AutoStartProfile could be called from SystemDomain
-#if defined(FEATURE_CORECLR)
ICLRPrivBinder * m_pBinderContext;
-#endif
SString m_fullFileName;
MulticoreJitPlayerStat & m_stats;
LIMITED_METHOD_CONTRACT;
m_pDomain = pDomain;
-#if defined(FEATURE_CORECLR)
m_pBinderContext = pBinderContext;
-#endif
m_JitInfoCount = 0;
m_ModuleCount = 0;
m_ModuleDepCount = 0;
LIMITED_METHOD_CONTRACT;
m_DomainID = pDomain->GetId();
-#if defined(FEATURE_CORECLR)
m_pBinderContext = pBinderContext;
-#endif
m_nMySession = nSession;
m_moduleCount = 0;
m_headerModuleCount = 0;
return false;
}
-#if defined(FEATURE_CORECLR)
if (pFile->GetPath().IsEmpty()) // Ignore in-memory modules
{
return false;
}
-#endif
if (! fMethodJit)
m_stats.m_nTryCompiling ++;
-#if defined(FEATURE_CORECLR)
// Reset the flag to allow managed code to be called in multicore JIT background thread from this routine
ThreadStateNCStackHolder holder(-1, Thread::TSNC_CallingManagedCodeDisabled);
-#endif
// MakeJitWorker calls back to MulticoreJitCodeStorage::StoreMethodCode under MethodDesc lock
pMD->MakeJitWorker(& header, CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_MCJIT_BACKGROUND));
PlayerModuleInfo & mod = m_pModules[moduleTo];
-#if defined(FEATURE_CORECLR)
// Load the module if necessary.
if (!mod.m_pModule)
{
}
}
}
-#endif
if (mod.UpdateNeedLevel((FileLoadLevel) level))
{
return true;
}
-#if defined(FEATURE_CORECLR)
DomainAssembly * MulticoreJitProfilePlayer::LoadAssembly(SString & assemblyName)
{
STANDARD_VM_CONTRACT;
return pDomainAssembly;
}
-#endif
inline bool MethodJifInfo(unsigned inst)
}
else
{
-#if !defined(FEATURE_CORECLR)
- if (m_nBlockingCount != 0)
- {
- if (! GroupWaitForModuleLoad(m_stats.m_nTotalMethod + pos)) // wait for blocking modules
- {
- goto Abort;
- }
-
- _ASSERTE(m_nBlockingCount == 0);
- }
-#endif
// To reduce contention with foreground thread, walk backward within the group of methods Jittable methods, not broken apart by dependency
{
PlayerModuleInfo & mod = m_pModules[inst >> 24];
-#if defined(FEATURE_CORECLR)
_ASSERTE(mod.IsModuleLoaded());
-#else
- _ASSERTE(mod.IsModuleLoaded() && ! mod.IsLowerLevel());
-#endif
if (mod.m_enableJit)
{
const ModuleRecord * pRec = (const ModuleRecord * ) pBuffer;
if (((unsigned)(pRec->lenModuleName
-#if defined(FEATURE_CORECLR)
+ pRec->lenAssemblyName
-#endif
) > (rcdLen - sizeof(ModuleRecord))) ||
(m_moduleCount >= m_headerModuleCount))
{
// no user delegate to callback
_ASSERTE((overlapped->m_iocbHelper == NULL) || !"This is benign, but should be optimized");
-#ifndef FEATURE_CORECLR
- if (g_pAsyncFileStream_AsyncResultClass)
- {
- SetAsyncResultProperties(overlapped, *errorCode, *numBytes);
- }
- else
-#endif // !FEATURE_CORECLR
{
//We're not initialized yet, go back to the Vm, and process the packet there.
ThreadpoolMgr::StoreOverlappedInfoInThread(pThread, *errorCode, *numBytes, key, *lpOverlapped);
#include "common.h"
-#ifndef FEATURE_CORECLR
-#include "ngenoptout.h"
-#include "assemblynamelist.h"
-
-AssemblyNameList g_NgenOptoutList;
-
-BOOL IsNativeImageOptedOut(IAssemblyName* pName)
-{
- WRAPPER_NO_CONTRACT
- return g_NgenOptoutList.Lookup(pName) != NULL;
-}
-
-void AddNativeImageOptOut(IAssemblyName* pName)
-{
- WRAPPER_NO_CONTRACT
- pName->AddRef();
- g_NgenOptoutList.Add(pName);
-}
-// HRESULT
-HRESULT RuntimeIsNativeImageOptedOut(IAssemblyName* pName)
-{
- WRAPPER_NO_CONTRACT
- return IsNativeImageOptedOut(pName) ? S_OK :S_FALSE;
-}
-#endif // FEATURE_CORECLR
#ifdef FEATURE_REMOTING
this == OBJECTREFToObject(((ThreadBaseObject *)from)->m_ExposedContext) ||
#endif
-#ifndef FEATURE_CORECLR
- this == OBJECTREFToObject(((ThreadBaseObject *)from)->m_ExecutionContext) ||
-#endif
false))
{
if (((ThreadBaseObject *)from)->m_InternalThread)
#endif // FEATURE_REMOTING
-#ifndef FEATURE_CORECLR
-class ExecutionContextObject : public Object
-{
- friend class MscorlibBinder;
-
- // These fields are also defined in the managed representation. (ExecutionContext.cs) If you
- // add or change these fields you must also change the managed code so that
- // it matches these. This is necessary so that the object is the proper
- // size.
-private :
-#ifdef FEATURE_CAS_POLICY
- OBJECTREF _hostExecutionContext;
-#endif // FEATURE_CAS_POLICY
- OBJECTREF _syncContext;
- OBJECTREF _syncContextNoFlow;
-#if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
- SECURITYCONTEXTREF _securityContext;
-#endif // #if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
-#ifdef FEATURE_REMOTING
- LOGICALCALLCONTEXTREF _logicalCallContext;
- OBJECTREF _illogicalCallContext;
-#endif // #ifdef FEATURE_REMOTING
- INT32 _flags;
- OBJECTREF _localValues;
- OBJECTREF _localChangeNotifications;
-
-public:
- OBJECTREF GetSynchronizationContext()
- {
- LIMITED_METHOD_CONTRACT;
- return _syncContext;
- }
-#if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
- SECURITYCONTEXTREF GetSecurityContext()
- {
- LIMITED_METHOD_CONTRACT;
- return _securityContext;
- }
-#endif // #if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
-#ifdef FEATURE_REMOTING
- LOGICALCALLCONTEXTREF GetLogicalCallContext()
- {
- LIMITED_METHOD_CONTRACT;
- return _logicalCallContext;
- }
- void SetLogicalCallContext(LOGICALCALLCONTEXTREF ref)
- {
- WRAPPER_NO_CONTRACT;
- SetObjectReferenceUnchecked((OBJECTREF*)&_logicalCallContext, (OBJECTREF)ref);
- }
- OBJECTREF GetIllogicalCallContext()
- {
- LIMITED_METHOD_CONTRACT;
- return _illogicalCallContext;
- }
- void SetIllogicalCallContext(OBJECTREF ref)
- {
- WRAPPER_NO_CONTRACT;
- SetObjectReferenceUnchecked((OBJECTREF*)&_illogicalCallContext, ref);
- }
-#endif //#ifdef FEATURE_REMOTING
-#ifdef FEATURE_COMPRESSEDSTACK
- COMPRESSEDSTACKREF GetCompressedStack()
- {
- WRAPPER_NO_CONTRACT;
- if (_securityContext != NULL)
- return _securityContext->GetCompressedStack();
- return NULL;
- }
-#endif // #ifdef FEATURE_COMPRESSEDSTACK
-
-};
-#endif //FEATURE_CORECLR
#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
typedef SynchronizationContextObject* SYNCHRONIZATIONCONTEXTREF;
#endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
-#ifndef FEATURE_CORECLR
-typedef ExecutionContextObject* EXECUTIONCONTEXTREF;
-#endif
typedef CultureInfoBaseObject* CULTUREINFOBASEREF;
typedef PTR_ArrayBase ARRAYBASEREF;
#endif
private:
OBJECTREF compareInfo;
OBJECTREF textInfo;
-#ifndef FEATURE_CORECLR
- OBJECTREF regionInfo;
-#endif // !FEATURE_CORECLR
OBJECTREF numInfo;
OBJECTREF dateTimeInfo;
OBJECTREF calendar;
#ifdef FEATURE_REMOTING
OBJECTREF m_ExposedContext;
#endif
-#ifdef FEATURE_CORECLR
OBJECTREF m_ExecutionContext;
OBJECTREF m_SynchronizationContext;
-#else
- EXECUTIONCONTEXTREF m_ExecutionContext;
-#endif
OBJECTREF m_Name;
OBJECTREF m_Delegate;
#ifdef FEATURE_LEAK_CULTURE_INFO
#endif // FEATURE_LEAK_CULTURE_INFO
#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
-#ifdef FEATURE_CORECLR
OBJECTREF GetSynchronizationContext()
{
LIMITED_METHOD_CONTRACT;
return m_SynchronizationContext;
}
-#else // !FEATURE_CORECLR
- OBJECTREF GetSynchronizationContext()
- {
- LIMITED_METHOD_CONTRACT;
- if (m_ExecutionContext != NULL)
- {
- return m_ExecutionContext->GetSynchronizationContext();
- }
- return NULL;
- }
-#endif // FEATURE_CORECLR
#endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
-#ifndef FEATURE_CORECLR
- OBJECTREF GetExecutionContext()
- {
- LIMITED_METHOD_CONTRACT;
- return (OBJECTREF)m_ExecutionContext;
- }
- void SetExecutionContext(OBJECTREF ref)
- {
- LIMITED_METHOD_CONTRACT;
- SetObjectReferenceUnchecked((OBJECTREF*)&m_ExecutionContext, ref);
- }
-#endif //!FEATURE_CORECLR
#ifdef FEATURE_COMPRESSEDSTACK
COMPRESSEDSTACKREF GetCompressedStack()
{
OBJECTREF m_pProcessExitEventHandler; // Delegate for 'process exit' event. Only used in Default appdomain.
OBJECTREF m_pDomainUnloadEventHandler; // Delegate for 'about to unload domain' event
OBJECTREF m_pUnhandledExceptionEventHandler; // Delegate for 'unhandled exception' event
-#ifdef FEATURE_APTCA
- OBJECTREF m_aptcaVisibleAssemblies; // array of conditional APTCA assembly names that should be APTCA visible
-#endif
OBJECTREF m_compatFlags;
#endif // FEATURE_EXCEPTION_NOTIFICATIONS
AppDomain* m_pDomain; // Pointer to the BaseDomain Structure
-#ifdef FEATURE_CAS_POLICY
- INT32 m_iPrincipalPolicy; // Type of principal to create by default
-#endif
CLR_BOOL m_bHasSetPolicy; // SetDomainPolicy has been called for this domain
CLR_BOOL m_bIsFastFullTrustDomain; // We know for sure that this is a homogeneous full trust domain.
CLR_BOOL m_compatFlagsInitialized;
return !!m_bIsFastFullTrustDomain;
}
-#ifdef FEATURE_APTCA
- OBJECTREF GetPartialTrustVisibleAssemblies()
- {
- LIMITED_METHOD_CONTRACT
- return m_aptcaVisibleAssemblies;
- }
-#endif // FEATURE_APTCA
// Ref needs to be a PTRARRAYREF
void SetPolicies(OBJECTREF ref)
#endif // FEATURE_EXCEPTION_NOTIFICATIONS
};
-#ifndef FEATURE_CORECLR
-// The managed definition of AppDomainSortingSetupInfo is in BCL\System\Globalization\AppDomainSortingSetupInfo.cs
-class AppDomainSortingSetupInfoObject : public Object
-{
- friend class MscorlibBinder;
-
- protected:
- INT_PTR m_pfnIsNLSDefinedString;
- INT_PTR m_pfnCompareStringEx;
- INT_PTR m_pfnLCMapStringEx;
- INT_PTR m_pfnFindNLSStringEx;
- INT_PTR m_pfnCompareStringOrdinal;
- INT_PTR m_pfnGetNLSVersionEx;
- INT_PTR m_pfnFindStringOrdinal;
- CLR_BOOL m_useV2LegacySorting;
- CLR_BOOL m_useV4LegacySorting;
-
- protected:
- AppDomainSortingSetupInfoObject() { LIMITED_METHOD_CONTRACT; }
- ~AppDomainSortingSetupInfoObject() { LIMITED_METHOD_CONTRACT; }
-
- public:
- CLR_BOOL UseV2LegacySorting() { LIMITED_METHOD_CONTRACT; return m_useV2LegacySorting; }
- CLR_BOOL UseV4LegacySorting() { LIMITED_METHOD_CONTRACT; return m_useV4LegacySorting; }
-
- INT_PTR GetPFNIsNLSDefinedString() { LIMITED_METHOD_CONTRACT; return m_pfnIsNLSDefinedString; }
- INT_PTR GetPFNCompareStringEx() { LIMITED_METHOD_CONTRACT; return m_pfnCompareStringEx; }
- INT_PTR GetPFNLCMapStringEx() { LIMITED_METHOD_CONTRACT; return m_pfnLCMapStringEx; }
- INT_PTR GetPFNFindNLSStringEx() { LIMITED_METHOD_CONTRACT; return m_pfnFindNLSStringEx; }
- INT_PTR GetPFNCompareStringOrdinal() { LIMITED_METHOD_CONTRACT; return m_pfnCompareStringOrdinal; }
- INT_PTR GetPFNGetNLSVersionEx() { LIMITED_METHOD_CONTRACT; return m_pfnGetNLSVersionEx; }
- INT_PTR GetPFNFindStringOrdinal() { LIMITED_METHOD_CONTRACT; return m_pfnFindStringOrdinal; }
-};
-typedef DPTR(AppDomainSortingSetupInfoObject) PTR_AppDomainSortingSetupInfoObject;
-#ifdef USE_CHECKED_OBJECTREFS
-typedef REF<AppDomainSortingSetupInfoObject> APPDOMAINSORTINGSETUPINFOREF;
-#else
-typedef AppDomainSortingSetupInfoObject* APPDOMAINSORTINGSETUPINFOREF;
-#endif // USE_CHECKED_OBJECTREFS
-#endif // FEATURE_CORECLR
// The managed definition of AppDomainSetup is in BCL\System\AppDomainSetup.cs
class AppDomainSetupObject : public Object
I1ARRAYREF m_ConfigurationBytes;
STRINGREF m_AppDomainManagerAssembly;
STRINGREF m_AppDomainManagerType;
-#if FEATURE_APTCA
- PTRARRAYREF m_AptcaVisibleAssemblies;
-#endif
OBJECTREF m_CompatFlags;
STRINGREF m_TargetFrameworkName;
-#ifndef FEATURE_CORECLR
- APPDOMAINSORTINGSETUPINFOREF m_AppDomainSortingSetupInfo;
-#endif // FEATURE_CORECLR
INT32 m_LoaderOptimization;
#ifdef FEATURE_COMINTEROP
CLR_BOOL m_DisableInterfaceCache;
~AppDomainSetupObject() { LIMITED_METHOD_CONTRACT; }
public:
-#ifndef FEATURE_CORECLR
- APPDOMAINSORTINGSETUPINFOREF GetAppDomainSortingSetupInfo() { LIMITED_METHOD_CONTRACT; return m_AppDomainSortingSetupInfo; }
-#endif // FEATURE_CORECLR
#ifdef FEATURE_RANDOMIZED_STRING_HASHING
BOOL UseRandomizedStringHashing() { LIMITED_METHOD_CONTRACT; return (BOOL) m_UseRandomizedStringHashing; }
#endif // FEATURE_RANDOMIZED_STRING_HASHING
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
if (AppX::IsAppXProcess())
{
COMPlusThrow(kPlatformNotSupportedException, IDS_EE_BADMARSHAL_TYPE_VARIANTASOBJECT);
}
-#endif // FEATURE_CORECLR
SafeVariantClear(pOle);
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
if (AppX::IsAppXProcess())
{
COMPlusThrow(kPlatformNotSupportedException, IDS_EE_BADMARSHAL_TYPE_VARIANTASOBJECT);
}
-#endif // FEATURE_CORECLR
HRESULT hr = MarshalCommonOleRefVariantForObject(pObj, pOle);
}
CONTRACT_END;
-#ifdef FEATURE_CORECLR
if (AppX::IsAppXProcess())
{
COMPlusThrow(kPlatformNotSupportedException, IDS_EE_BADMARSHAL_TYPE_VARIANTASOBJECT);
}
-#endif // FEATURE_CORECLR
#ifdef MDA_SUPPORTED
MdaInvalidVariant* pProbe = MDA_GET_ASSISTANT(InvalidVariant);
#include "../binder/inc/coreclrbindercommon.h"
#endif
-#ifdef FEATURE_CAS_POLICY
-#include <wintrust.h>
-#endif
#ifdef FEATURE_PREJIT
#include "compile.h"
m_pMDImport(NULL),
m_pImporter(NULL),
m_pEmitter(NULL),
-#ifndef FEATURE_CORECLR
- m_pAssemblyImporter(NULL),
- m_pAssemblyEmitter(NULL),
-#endif
m_pMetadataLock(::new SimpleRWLock(PREEMPTIVE, LOCK_TYPE_DEFAULT)),
m_refCount(1),
m_hash(NULL),
m_flags(0),
m_fStrongNameVerified(FALSE)
-#ifdef FEATURE_CAS_POLICY
- ,m_certificate(NULL),
- m_fCheckedCertificate(FALSE)
- ,m_pSecurityManager(NULL)
- ,m_securityManagerLock(CrstPEFileSecurityManager)
-#endif // FEATURE_CAS_POLICY
,m_pHostAssembly(nullptr)
#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
,m_pFallbackLoadContextBinder(nullptr)
}
-#ifdef FEATURE_CAS_POLICY
- if (fCheckAuthenticodeSignature)
- {
- CheckAuthenticodeSignature();
- }
-#endif // FEATURE_CAS_POLICY
}
m_identity->Release();
if (m_pMetadataLock)
delete m_pMetadataLock;
-#ifdef FEATURE_CAS_POLICY
- if (m_pSecurityManager) {
- m_pSecurityManager->Release();
- m_pSecurityManager = NULL;
- }
- if (m_certificate && !g_pCertificateCache->Contains(m_certificate))
- CoTaskMemFree(m_certificate);
-#endif // FEATURE_CAS_POLICY
if (m_pHostAssembly != NULL)
{
result.SetUTF8(GetSimpleName());
}
-#ifdef FEATURE_CAS_POLICY
-
-// Returns security information for the assembly based on the codebase
-void PEFile::GetSecurityIdentity(SString &codebase, SecZone *pdwZone, DWORD dwFlags, BYTE *pbUniqueID, DWORD *pcbUniqueID)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pdwZone));
- PRECONDITION(CheckPointer(pbUniqueID));
- PRECONDITION(CheckPointer(pcbUniqueID));
- }
- CONTRACTL_END;
-
- if (IsAssembly())
- {
- ((PEAssembly*)this)->GetCodeBase(codebase);
- }
- else if (m_identity != NULL && !m_identity->GetPath().IsEmpty())
- {
- codebase.Set(W("file:///"));
- codebase.Append(m_identity->GetPath());
- }
- else
- {
- _ASSERTE( !"Unable to determine security identity" );
- }
-
- GCX_PREEMP();
-
- if(!codebase.IsEmpty())
- {
- *pdwZone = NoZone;
-
- InitializeSecurityManager();
-
- // We have a class name, return a class factory for it
- _ASSERTE(sizeof(SecZone) == sizeof(DWORD));
- IfFailThrow(m_pSecurityManager->MapUrlToZone(codebase,
- reinterpret_cast<DWORD *>(pdwZone),
- dwFlags));
-
- if (*pdwZone>=NumZones)
- IfFailThrow(SecurityPolicy::ApplyCustomZoneOverride(pdwZone));
-
- IfFailThrow(m_pSecurityManager->GetSecurityId(codebase,
- pbUniqueID,
- pcbUniqueID,
- 0));
- }
-}
-
-void PEFile::InitializeSecurityManager()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- CAN_TAKE_LOCK;
- MODE_PREEMPTIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- if(m_pSecurityManager == NULL)
- {
- CrstHolder holder(&m_securityManagerLock);
- if (m_pSecurityManager == NULL)
- {
- IfFailThrow(CoInternetCreateSecurityManager(NULL,
- &m_pSecurityManager,
- 0));
- }
- }
-}
-
-#endif // FEATURE_CAS_POLICY
// ------------------------------------------------------------
// Checks
CHECK_OK;
}
-#ifndef FEATURE_CORECLR
-// ------------------------------------------------------------
-// Hash support
-// ------------------------------------------------------------
-
-#ifndef SHA1_HASH_SIZE
-#define SHA1_HASH_SIZE 20
-#endif
-
-void PEFile::GetSHA1Hash(SBuffer &result)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- PRECONDITION(CheckValue(result));
- THROWS;
- MODE_ANY;
- GC_TRIGGERS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- // Cache the SHA1 hash in a buffer
- if (m_hash == NULL)
- {
- // We shouldn't have to compute a SHA1 hash in any scenarios
- // where the image opening should be suppressed.
- EnsureImageOpened();
-
- m_hash = new InlineSBuffer<SHA1_HASH_SIZE>();
- GetILimage()->ComputeHash(CALG_SHA1, *m_hash);
- }
-
- result.Set(*m_hash);
-}
-#endif // FEATURE_CORECLR
// ------------------------------------------------------------
// Metadata access
return;
#ifdef FEATURE_PREJIT
if (m_nativeImage != NULL
-#ifdef FEATURE_CORECLR
&& m_nativeImage->GetMDImport() != NULL
-#endif
)
{
// Use native image for metadata
pIMDEmit->Release();
}
-#ifndef FEATURE_CORECLR
-void PEFile::OpenAssemblyImporter()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- // Make sure internal MD is in RW format.
- ConvertMDInternalToReadWrite();
-
- // Get the interface
- IMetaDataAssemblyImport *pIMDAImport = NULL;
- IfFailThrow(GetMetaDataPublicInterfaceFromInternal((void*)GetPersistentMDImport(),
- IID_IMetaDataAssemblyImport,
- (void **)&pIMDAImport));
-
- // Atomically swap it into the field (release it if we lose the race)
- if (FastInterlockCompareExchangePointer(&m_pAssemblyImporter, pIMDAImport, NULL) != NULL)
- pIMDAImport->Release();
-}
-
-void PEFile::OpenAssemblyEmitter()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- // Make sure internal MD is in RW format.
- ConvertMDInternalToReadWrite();
-
- IMetaDataAssemblyEmit *pIMDAssemblyEmit = NULL;
- IfFailThrow(GetMetaDataPublicInterfaceFromInternal((void*)GetPersistentMDImport(),
- IID_IMetaDataAssemblyEmit,
- (void **)&pIMDAssemblyEmit));
-
- // Atomically swap it into the field (release it if we lose the race)
- if (FastInterlockCompareExchangePointer(&m_pAssemblyEmitter, pIMDAssemblyEmit, NULL) != NULL)
- pIMDAssemblyEmit->Release();
-}
-#endif // FEATURE_CORECLR
void PEFile::ReleaseMetadataInterfaces(BOOL bDestructor, BOOL bKeepNativeData/*=FALSE*/)
{
}
CONTRACTL_END;
_ASSERTE(bDestructor || !m_bHasPersistentMDImport);
-#ifndef FEATURE_CORECLR
- if (m_pAssemblyImporter != NULL)
- {
- m_pAssemblyImporter->Release();
- m_pAssemblyImporter = NULL;
- }
- if(m_pAssemblyEmitter)
- {
- m_pAssemblyEmitter->Release();
- m_pAssemblyEmitter=NULL;
- }
-#endif
if (m_pImporter != NULL)
{
}
}
-#ifdef FEATURE_CAS_POLICY
-
-void PEFile::CheckAuthenticodeSignature()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- // Check any security signature in the header.
-
- // This publisher data can potentially be cached and passed back in via
- // PEAssembly::CreateDelayed.
- //
- // HOWEVER - even if we cache it, the certificate still may need to be verified at
- // load time. The only real caching can be done when the COR_TRUST certificate is
- // ABSENT.
- //
- // (In the case where it is present, we could still theoretically
- // cache the certificate and re-verify it and at least avoid touching the image
- // again, however this path is not implemented yet, so this is TBD if we decide
- // it is an important case to optimize for.)
-
- if (!HasSecurityDirectory())
- {
- LOG((LF_SECURITY, LL_INFO1000, "No certificates found in module\n"));
- }
- else if(g_pConfig->GeneratePublisherEvidence())
- {
- // <TODO>@todo: Just because we don't have a file path, doesn't mean we can't have a certicate (does it?)</TODO>
- if (!GetPath().IsEmpty())
- {
- GCX_PREEMP();
-
- // Ignore any errors here - if we fail to validate a certificate, we just don't
- // include it as evidence.
-
- DWORD size;
- CoTaskNewHolder<COR_TRUST> pCor = NULL;
- // Failing to find a signature is OK.
- LPWSTR pFileName = (LPWSTR) GetPath().GetUnicode();
- DWORD dwAuthFlags = COR_NOUI|COR_NOPOLICY;
-#ifndef FEATURE_CORECLR
- // Authenticode Verification Start
- FireEtwAuthenticodeVerificationStart_V1(dwAuthFlags, 0, pFileName, GetClrInstanceId());
-#endif // !FEATURE_CORECLR
-
- HRESULT hr = ::GetPublisher(pFileName,
- NULL,
- dwAuthFlags,
- &pCor,
- &size);
-
-#ifndef FEATURE_CORECLR
- // Authenticode Verification End
- FireEtwAuthenticodeVerificationStop_V1(dwAuthFlags, (ULONG)hr, pFileName, GetClrInstanceId());
-#endif // !FEATURE_CORECLR
-
- if( SUCCEEDED(hr) ) {
- DWORD index = 0;
- EnumCertificateAdditionFlags dwFlags = g_pCertificateCache->AddEntry(pCor, &index);
- switch (dwFlags) {
- case CacheSaturated:
- pCor.SuppressRelease();
- m_certificate = pCor.GetValue();
- break;
-
- case Success:
- pCor.SuppressRelease();
- // falling through
- case AlreadyExists:
- m_certificate = g_pCertificateCache->GetEntry(index);
- _ASSERTE(m_certificate);
- break;
- }
- }
- }
- }
- else
- {
- LOG((LF_SECURITY, LL_INFO1000, "Assembly has an Authenticode signature, but Publisher evidence has been disabled.\n"));
- }
-
- m_fCheckedCertificate = TRUE;
-}
-
-HRESULT STDMETHODCALLTYPE
-GetPublisher(__in __in_z IN LPWSTR pwsFileName, // File name, this is required even with the handle
- IN HANDLE hFile, // Optional file name
- IN DWORD dwFlags, // COR_NOUI or COR_NOPOLICY
- OUT PCOR_TRUST *pInfo, // Returns a PCOR_TRUST (Use FreeM)
- OUT DWORD *dwInfo) // Size of pInfo.
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- GUID gV2 = COREE_POLICY_PROVIDER;
- COR_POLICY_PROVIDER sCorPolicy;
-
- WINTRUST_DATA sWTD;
- WINTRUST_FILE_INFO sWTFI;
-
- // Set up the COR trust provider
- memset(&sCorPolicy, 0, sizeof(COR_POLICY_PROVIDER));
- sCorPolicy.cbSize = sizeof(COR_POLICY_PROVIDER);
-
- // Set up the winverify provider structures
- memset(&sWTD, 0x00, sizeof(WINTRUST_DATA));
- memset(&sWTFI, 0x00, sizeof(WINTRUST_FILE_INFO));
-
- sWTFI.cbStruct = sizeof(WINTRUST_FILE_INFO);
- sWTFI.hFile = hFile;
- sWTFI.pcwszFilePath = pwsFileName;
-
- sWTD.cbStruct = sizeof(WINTRUST_DATA);
- sWTD.pPolicyCallbackData = &sCorPolicy; // Add in the cor trust information!!
- if (dwFlags & COR_NOUI)
- {
- sWTD.dwUIChoice = WTD_UI_NONE; // No bad UI is overridden in COR TRUST provider
- }
- else
- {
- sWTD.dwUIChoice = WTD_UI_ALL; // No bad UI is overridden in COR TRUST provider
- }
- sWTD.dwUnionChoice = WTD_CHOICE_FILE;
- sWTD.pFile = &sWTFI;
-
- // Set the policies for the VM (we have stolen VMBased and use it like a flag)
- if (dwFlags != 0)
- sCorPolicy.VMBased = dwFlags;
-
- LeaveRuntimeHolder holder((size_t)WinVerifyTrust);
-
- // WinVerifyTrust calls mscorsecimpl.dll to do the policy check
- hr = WinVerifyTrust(GetFocus(), &gV2, &sWTD);
-
- *pInfo = sCorPolicy.pbCorTrust;
- *dwInfo = sCorPolicy.cbCorTrust;
-
- return hr;
-} // GetPublisher
-
-#endif // FEATURE_CAS_POLICY
// ------------------------------------------------------------
// PE file access
static const LPCWSTR CorCompileRuntimeDllNames[NUM_RUNTIME_DLLS] =
{
-#ifdef FEATURE_CORECLR
MAKEDLLNAME_W(W("coreclr")),
-#else
- MAKEDLLNAME_W(W("CLR")),
-#endif
MAKEDLLNAME_W(W("clrjit"))
};
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-static LPCWSTR s_ngenCompilerDllName = NULL;
-#endif //!FEATURE_CORECLR && !CROSSGEN_COMPILE
LPCWSTR CorCompileGetRuntimeDllName(CorCompileRuntimeDlls id)
{
}
CONTRACTL_END;
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- if (id == NGEN_COMPILER_INFO)
- {
- // The NGen compiler needs to be handled differently as it can be customized,
- // unlike the other runtime DLLs.
-
- if (s_ngenCompilerDllName == NULL)
- {
- // Check if there is an override for the compiler DLL
- LPCWSTR ngenCompilerOverride = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_NGen_JitName);
-
- if (ngenCompilerOverride == NULL)
- {
- s_ngenCompilerDllName = DEFAULT_NGEN_COMPILER_DLL_NAME;
- }
- else
- {
- if (wcsstr(ngenCompilerOverride, W(".dll")) == NULL)
- {
- EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_EXECUTIONENGINE,
- NGEN_COMPILER_OVERRIDE_KEY W(" should have a .DLL suffix"));
- }
-
- s_ngenCompilerDllName = ngenCompilerOverride;
- }
- }
-
- return s_ngenCompilerDllName;
- }
-#endif //!FEATURE_CORECLR && !CROSSGEN_COMPILE
return CorCompileRuntimeDllNames[id];
}
CONTRACTL_END;
// Currently special cased for every entry.
-#ifdef FEATURE_CORECLR
static_assert_no_msg(NUM_RUNTIME_DLLS == 2);
static_assert_no_msg(CORECLR_INFO == 0);
-#else // !FEATURE_CORECLR
- static_assert_no_msg(NUM_RUNTIME_DLLS == 2);
- static_assert_no_msg(CLR_INFO == 0);
- static_assert_no_msg(NGEN_COMPILER_INFO == 1);
-#endif // else FEATURE_CORECLR
HMODULE hMod = NULL;
// Try to load the correct DLL
switch (id)
{
-#ifdef FEATURE_CORECLR
case CORECLR_INFO:
hMod = GetCLRModule();
break;
-#else // !FEATURE_CORECLR
- case CLR_INFO:
- hMod = GetCLRModule();
- break;
-
- case NGEN_COMPILER_INFO:
- hMod = s_ngenCompilerDll;
- break;
-#endif // else FEATURE_CORECLR
default:
COMPlusThrowNonLocalized(kExecutionEngineException,
{
STANDARD_VM_CONTRACT;
-#if !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- //
- // We will automatically fail any zap files which were compiled with different runtime dlls.
- // This is so that we don't load bad ngen images after recompiling or patching the runtime.
- //
-
- for (DWORD index = 0; index < NUM_RUNTIME_DLLS; index++)
- {
- HMODULE hMod = CorCompileGetRuntimeDll((CorCompileRuntimeDlls)index);
-
- if (hMod == NULL)
- {
- // Unless this is an NGen worker process, we don't want to load JIT compiler just to do a timestamp check.
- // In an ideal case, all assemblies have native images, and JIT compiler never needs to be loaded at runtime.
- // Loading JIT compiler just to check its timestamp would reduce the benefits of have native images.
- // Since CLR and JIT are intended to be serviced together, the possibility of accidentally using native
- // images created by an older JIT is very small, and is deemed an acceptable risk.
- // Note that when multiple JIT compilers are used (e.g., clrjit.dll and compatjit.dll on x64 in .NET 4.6),
- // they must all be in the same patch family.
- if (!IsCompilationProcess())
- continue;
-
- // If we are doing ngen, then eagerly make sure all the system
- // dependencies are loaded. Else ICorCompileInfo::CheckAssemblyZap()
- // will not work correctly.
-
- LPCWSTR wszDllName = CorCompileGetRuntimeDllName((CorCompileRuntimeDlls)index);
- if (FAILED(g_pCLRRuntime->LoadLibrary(wszDllName, &hMod)))
- {
- EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_EXECUTIONENGINE, W("Unable to load CLR DLL during ngen"));
- }
- }
-
- _ASSERTE(hMod != NULL);
-
- PEDecoder pe(hMod);
-
- // Match NT header timestamp and checksum to test DLL identity
-
- if ((info->runtimeDllInfo[index].timeStamp == pe.GetTimeDateStamp()
- || info->runtimeDllInfo[index].timeStamp == 0)
- && (info->runtimeDllInfo[index].virtualSize == pe.GetVirtualSize()
- || info->runtimeDllInfo[index].virtualSize == 0))
- {
- continue;
- }
-
- {
- // set "ComPlus_CheckNGenImageTimeStamp" to 0 to ignore time-stamp-checking
- static ConfigDWORD checkNGenImageTimeStamp;
- BOOL enforceCheck = checkNGenImageTimeStamp.val(CLRConfig::EXTERNAL_CheckNGenImageTimeStamp);
-
- RuntimeVerifyLog(enforceCheck ? LL_ERROR : LL_WARNING,
- pLogAsm,
- W("Compiled with different CLR DLL (%s). Exact match expected."),
- CorCompileGetRuntimeDllName((CorCompileRuntimeDlls)index));
-
- if (enforceCheck)
- return FALSE;
- }
- }
-#endif // !CROSSGEN_COMPILE && !FEATURE_CORECLR
return TRUE;
}
if (!image->CheckNativeHeaderVersion())
{
-#ifdef FEATURE_CORECLR
// Wrong native image version is fatal error on CoreCLR
ThrowHR(COR_E_NI_AND_RUNTIME_VERSION_MISMATCH);
-#else
- return FALSE;
-#endif
}
CORCOMPILE_VERSION_INFO *info = image->GetNativeVersionInfo();
LoggablePEAssembly logAsm(this);
if (!RuntimeVerifyNativeImageVersion(info, &logAsm))
{
-#ifdef FEATURE_CORECLR
// Wrong native image version is fatal error on CoreCLR
ThrowHR(COR_E_NI_AND_RUNTIME_VERSION_MISMATCH);
-#else
- return FALSE;
-#endif
}
-#ifdef FEATURE_CORECLR
CorCompileConfigFlags configFlags = PEFile::GetNativeImageConfigFlagsWithOverrides();
if (IsSystem())
{
return FALSE;
}
-#else
- //
- // Check image flavor. Skip this check in RuntimeVerifyNativeImageVersion called from fusion - fusion is responsible for choosing the right flavor.
- //
- if (!RuntimeVerifyNativeImageFlavor(info, &logAsm))
- {
- return FALSE;
- }
-#endif
return TRUE;
}
-#ifndef FEATURE_CORECLR
-//===========================================================================================================
-// Validates that an NI matches the required flavor (debug, instrumented, etc.)
-//
-//===========================================================================================================
-BOOL RuntimeVerifyNativeImageFlavor(const CORCOMPILE_VERSION_INFO *info, LoggableAssembly *pLogAsm)
-{
- STANDARD_VM_CONTRACT;
-
- CorCompileConfigFlags configFlags = PEFile::GetNativeImageConfigFlagsWithOverrides();
-
- if ((info->wConfigFlags & configFlags) != configFlags)
- return FALSE;
-
- return TRUE;
-}
-#endif
//===========================================================================================================
// Validates that an NI matches the running CLR, OS, CPU, etc.
}
#endif // CROSSGEN_COMPILE
-#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR)
- //
- // Check the right JIT compiler
- //
-
- bool nativeImageBuiltWithRyuJit = ((info->wCodegenFlags & CORCOMPILE_CODEGEN_USE_RYUJIT) != 0);
- if (UseRyuJit() != nativeImageBuiltWithRyuJit)
- {
- RuntimeVerifyLog(LL_ERROR, pLogAsm, W("JIT compiler used to generate native image doesn't match current JIT compiler."));
- return FALSE;
- }
-#endif
//
// The zap is up to date.
return GetLoadedIL()->GetTimeDateStamp();
}
-#ifdef FEATURE_CAS_POLICY
-
-//---------------------------------------------------------------------------------------
-//
-// Get a SafePEFileHandle for this PEFile
-//
-
-SAFEHANDLE PEFile::GetSafeHandle()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- SAFEHANDLE objSafeHandle = NULL;
-
- GCPROTECT_BEGIN(objSafeHandle);
-
- objSafeHandle = (SAFEHANDLE)AllocateObject(MscorlibBinder::GetClass(CLASS__SAFE_PEFILE_HANDLE));
- CallDefaultConstructor(objSafeHandle);
-
- this->AddRef();
- objSafeHandle->SetHandle(this);
-
- GCPROTECT_END();
-
- return objSafeHandle;
-}
-
-#endif // FEATURE_CAS_POLICY
// ================================================================================
// PEAssembly class - a PEFile which represents an assembly
m_creator(clr::SafeAddRef(creator)),
m_bIsFromGAC(FALSE),
m_bIsOnTpaList(FALSE)
-#ifdef FEATURE_CORECLR
,m_fProfileAssembly(0)
-#else
- ,m_fStrongNameBypassed(FALSE)
-#endif
{
CONTRACTL
{
if (!image->CheckILFormat())
ThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL);
-#if !defined(FEATURE_CORECLR)
- if(pBinderToUse != NULL && !isIntrospectionOnly)
- {
- ReleaseHolder<ICLRPrivAssembly> pAsm;
- ReleaseHolder<IAssemblyName> pAssemblyName;
- IfFailThrow(pBinderToUse->BindAssemblyExplicit(image, &pAssemblyName, &pAsm));
- PEAssembly* pFile = nullptr;
- IfFailThrow(GetAppDomain()->BindHostedPrivAssembly(pParentAssembly, pAsm, pAssemblyName, &pFile));
- _ASSERTE(pFile);
- RETURN pFile;
- }
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_FUSION
RETURN new PEAssembly(image, NULL, NULL, NULL, NULL, NULL, NULL, pParentAssembly, FALSE, isIntrospectionOnly);
// checked, to handle the case where we are not loading m_image.
EnsureImageOpened();
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- if (IsWindowsRuntime())
- {
- // Winmd files are always loaded in full trust.
- m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
- m_fStrongNameVerified = TRUE;
- return;
- }
-#endif
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
if (m_nativeImage == NULL && !GetILimage()->IsTrustedNativeImage())
-#else
- if (!GetILimage()->IsTrustedNativeImage())
-#endif
{
if (!GetILimage()->CheckILFormat())
ThrowHR(COR_E_BADIMAGEFORMAT);
}
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- // Do not validate strong name signature during CrossGen. This is necessary
- // to make build-lab scenarios to work.
- if (IsCompilationProcess())
- {
- m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
- }
- else
-#endif
// Check the strong name if present.
if (IsIntrospectionOnly())
{
// need to do module hash checks.
m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
}
-#if !defined(FEATURE_CORECLR)
- //We do this to early out for WinMD files that are unsigned but have NI images as well.
- else if (!HasStrongNameSignature())
- {
-#ifdef FEATURE_CAS_POLICY
- // We only check module hashes if there is a strong name or Authenticode signature
- if (m_certificate == NULL)
- {
- m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
- }
-#endif
- }
-#endif // !defined(FEATURE_CORECLR)
else
{
-#ifdef FEATURE_CORECLR
// Runtime policy on CoreCLR is to skip verification of ALL assemblies
m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
m_fStrongNameVerified = TRUE;
-#else
- DWORD verifyOutputFlags = 0;
- HRESULT hr = GetILimage()->VerifyStrongName(&verifyOutputFlags);
-
- if (SUCCEEDED(hr))
- {
- // Strong name verified or delay sign OK'ed.
- // We will skip verification of modules in the delay signed case.
-
- if ((verifyOutputFlags & SN_OUTFLAG_WAS_VERIFIED) == 0)
- m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
- }
- else
- {
- // Strong name missing or error. Throw in the latter case.
- if (hr != CORSEC_E_MISSING_STRONGNAME)
- ThrowHR(hr);
-
-#ifdef FEATURE_CAS_POLICY
- // Since we are not strong named, don't check module hashes.
- // (Unless we have a security certificate, in which case check anyway.)
-
- if (m_certificate == NULL)
- m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
-#endif
- }
-
-#endif // FEATURE_CORECLR
}
m_fStrongNameVerified = TRUE;
}
-#ifdef FEATURE_CORECLR
BOOL PEAssembly::IsProfileAssembly()
{
CONTRACTL
m_fProfileAssembly = bProfileAssembly ? 1 : -1;
return bProfileAssembly;
}
-#endif // FEATURE_CORECLR
// ------------------------------------------------------------
// Descriptive strings
}
}
-#ifndef FEATURE_CORECLR
-BOOL PEAssembly::IsReportedToUsageLog()
-{
- LIMITED_METHOD_CONTRACT;
- BOOL fReported = TRUE;
-
- if (!IsDynamic())
- fReported = m_identity->IsReportedToUsageLog();
-
- return fReported;
-}
-
-void PEAssembly::SetReportedToUsageLog()
-{
- LIMITED_METHOD_CONTRACT;
-
- if (!IsDynamic())
- m_identity->SetReportedToUsageLog();
-}
-#endif // !FEATURE_CORECLR
#ifdef DACCESS_COMPILE
TADDR PEFile::GetMDInternalRWAddress()
PTR_ICLRPrivBinder pBindingContext = NULL;
-#if defined(FEATURE_CORECLR)
// Mscorlib is always bound in context of the TPA Binder. However, since it gets loaded and published
// during EEStartup *before* TPAbinder is initialized, we dont have a binding context to publish against.
// Thus, we will always return NULL for its binding context.
if (!IsSystem())
-#endif // defined(FEATURE_CORECLR)
{
pBindingContext = dac_cast<PTR_ICLRPrivBinder>(GetHostAssembly());
}
BOOL Equals(PEImage *pImage);
#endif // DACCESS_COMPILE
-#ifndef FEATURE_CORECLR
- BOOL IsShareable();
-#endif
void GetMVID(GUID *pMvid);
LPCSTR GetLocale();
DWORD GetFlags();
HRESULT GetFlagsNoTrigger(DWORD * pdwFlags);
-#ifdef FEATURE_CAS_POLICY
- COR_TRUST *GetAuthenticodeSignature();
-#endif
// ------------------------------------------------------------
// PE file access
// ------------------------------------------------------------
ULONG GetILImageTimeDateStamp();
-#ifdef FEATURE_CAS_POLICY
- SAFEHANDLE GetSafeHandle();
-#endif // FEATURE_CAS_POLICY
// ------------------------------------------------------------
// Image memory access
void ConvertMDInternalToReadWrite();
void ReleaseMetadataInterfaces(BOOL bDestructor, BOOL bKeepNativeData=FALSE);
-#ifdef FEATURE_CAS_POLICY
- // Check the Authenticode signature of a PE file
- void CheckAuthenticodeSignature();
-#endif // FEATURE_CAS_POLICY
friend class Module;
#ifdef FEATURE_PREJIT
#endif
IMetaDataImport2 *m_pImporter;
IMetaDataEmit *m_pEmitter;
-#ifndef FEATURE_CORECLR
- IMetaDataAssemblyImport *m_pAssemblyImporter;
- IMetaDataAssemblyEmit *m_pAssemblyEmitter;
-#endif
SimpleRWLock *m_pMetadataLock;
Volatile<LONG> m_refCount;
SBuffer *m_hash; // cached SHA1 hash value
int m_flags;
BOOL m_fStrongNameVerified;
-#ifdef FEATURE_CAS_POLICY
- COR_TRUST *m_certificate;
- BOOL m_fCheckedCertificate;
- IInternetSecurityManager *m_pSecurityManager;
- Crst m_securityManagerLock;
-#endif // FEATURE_CAS_POLICY
#ifdef DEBUGGING_SUPPORTED
#ifdef FEATURE_PREJIT
// Public API
// ------------------------------------------------------------
-#if !defined(FEATURE_CORECLR)
- static PEAssembly * Open(
- PEAssembly * pParentAssembly,
- PEImage * pPEImageIL,
- PEImage * pPEImageNI,
- ICLRPrivAssembly * pHostAssembly,
- BOOL fIsIntrospectionOnly);
-
- static PEAssembly * Open(
- PEAssembly * pParentAssembly,
- PEImage * pPEImageIL,
- BOOL isIntrospectionOnly = FALSE);
-#else //!FEATURE_CORECLR
// CoreCLR's PrivBinder PEAssembly creation entrypoint
static PEAssembly * Open(
PEAssembly * pParent,
PEImage * pPEImageNI,
ICLRPrivAssembly * pHostAssembly,
BOOL fIsIntrospectionOnly = FALSE);
-#endif //!FEATURE_CORECLR
// This opens the canonical mscorlib.dll
#ifdef FEATURE_FUSION
// ------------------------------------------------------------
BOOL IsSourceGAC();
-#ifdef FEATURE_CORECLR
BOOL IsProfileAssembly();
-#endif // FEATURE_CORECLR
ULONG HashIdentity();
#ifdef FEATURE_FUSION
#endif
#endif
-#ifndef FEATURE_CORECLR
- BOOL IsReportedToUsageLog();
- void SetReportedToUsageLog();
-#endif // !FEATURE_CORECLR
protected:
// things
SString m_sTextualIdentity;
#endif
-#ifdef FEATURE_CORECLR
int m_fProfileAssembly; // Tri-state cache
-#else
- BOOL m_fStrongNameBypassed;
-#endif
public:
PTR_PEFile GetCreator()
return (IsAfContentType_WindowsRuntime(GetFlags()));
}
-#ifndef FEATURE_CORECLR
-inline BOOL PEFile::IsShareable()
-{
- CONTRACTL
- {
- PRECONDITION(CheckPointer(m_identity));
- MODE_ANY;
- THROWS;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- if (!m_identity->HasID())
- return FALSE;
- return TRUE ;
-}
-#endif
inline void PEFile::GetMVID(GUID *pMvid)
{
CONTRACT_END;
*/
SUPPORTS_DAC;
-#ifndef FEATURE_CORECLR
-_ASSERTE(m_bHasPersistentMDImport);
-#endif
#if !defined(__GNUC__)
_ASSERTE(!IsResource());
RETURN m_pEmitter;
}
-#ifndef FEATURE_CORECLR
-inline IMetaDataAssemblyImport *PEFile::GetAssemblyImporter()
-{
- CONTRACT(IMetaDataAssemblyImport *)
- {
- INSTANCE_CHECK;
- MODE_ANY;
- GC_NOTRIGGER;
- PRECONDITION(!IsResource());
- POSTCONDITION(CheckPointer(RETVAL));
- PRECONDITION(m_bHasPersistentMDImport);
- THROWS;
- }
- CONTRACT_END;
-
- if (m_pAssemblyImporter == NULL)
- OpenAssemblyImporter();
-
- RETURN m_pAssemblyImporter;
-}
-
-inline IMetaDataAssemblyEmit *PEFile::GetAssemblyEmitter()
-{
- CONTRACT(IMetaDataAssemblyEmit *)
- {
- INSTANCE_CHECK;
- MODE_ANY;
- GC_NOTRIGGER;
- PRECONDITION(!IsResource());
- POSTCONDITION(CheckPointer(RETVAL));
- PRECONDITION(m_bHasPersistentMDImport);
- }
- CONTRACT_END;
-
- if (m_pAssemblyEmitter == NULL)
- OpenAssemblyEmitter();
-
- RETURN m_pAssemblyEmitter;
-}
-#endif // FEATURE_CORECLR
#endif // DACCESS_COMPILE
if (HasOpenedILimage())
{
-#if defined(FEATURE_PREJIT) && defined(FEATURE_CORECLR)
+#if defined(FEATURE_PREJIT)
if (m_openedILimage == m_nativeImage)
{
// On Apollo builds, we sometimes open the native image into the slot
return GetPersistentMDImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly), NULL, NULL, NULL, NULL, NULL, pdwFlags);
}
-#ifdef FEATURE_CAS_POLICY
-inline COR_TRUST *PEFile::GetAuthenticodeSignature()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- }
- CONTRACTL_END;
-
- if (!m_fCheckedCertificate && HasSecurityDirectory())
- {
- CheckAuthenticodeSignature();
- }
-
- return m_certificate;
-}
-#endif
// ------------------------------------------------------------
// Hash support
}
}
-#ifndef FEATURE_CORECLR
-//---------------------------------------------------------------------------------------
-//
-// Mark that an assembly has had its strong name verification bypassed
-//
-
-inline void PEAssembly::SetStrongNameBypassed()
-{
- LIMITED_METHOD_CONTRACT;
- m_fStrongNameBypassed = TRUE;
-}
-
-inline BOOL PEAssembly::NeedsModuleHashChecks()
-{
- LIMITED_METHOD_CONTRACT;
-
- return ((m_flags & PEFILE_SKIP_MODULE_HASH_CHECKS) == 0) && !m_fStrongNameBypassed;
-}
-#endif // FEATURE_CORECLR
-#ifdef FEATURE_CAS_POLICY
-//---------------------------------------------------------------------------------------
-//
-// Verify the Authenticode and strong name signatures of an assembly during the assembly
-// load code path. To verify the strong name signature outside of assembly load, use the
-// VefifyStrongName method instead.
-//
-// If the applicaiton is using strong name bypass, then this method may not cause a real
-// strong name verification, delaying the assembly's strong name load until we know that
-// the verification is required. If the assembly must be forced to have its strong name
-// verified, then the VerifyStrongName method should also be chosen.
-//
-// See code:AssemblySecurityDescriptor::ResolveWorker#StrongNameBypass
-//
-
-inline void PEAssembly::DoLoadSignatureChecks()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS; // Fusion uses crsts on AddRef/Release
- MODE_ANY;
- }
- CONTRACTL_END;
-
- ETWOnStartup(SecurityCatchCall_V1, SecurityCatchCallEnd_V1);
-
- // If this isn't mscorlib or a dynamic assembly, verify the Authenticode signature.
- if (IsSystem() || IsDynamic())
- {
- // If it was a dynamic module (or mscorlib), then we don't want to be doing module hash checks on it
- m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
- }
-
- // Check strong name signature. We only want to do this now if the application is not using the strong
- // name bypass feature. Otherwise we'll delay strong name verification until we figure out how trusted
- // the assembly is.
- //
- // For more information see code:AssemblySecurityDescriptor::ResolveWorker#StrongNameBypass
-
- // Make sure m_pMDImport is initialized as we need to call VerifyStrongName which calls GetFlags
- // BypassTrustedAppStrongNames = false is a relatively uncommon scenario so we need to make sure
- // the initialization order is always correct and we don't miss this uncommon case
- _ASSERTE(GetMDImport());
-
- if (!g_pConfig->BypassTrustedAppStrongNames())
- {
- VerifyStrongName();
- }
-}
-#endif // FEATURE_CAS_POLICY
// ------------------------------------------------------------
// Metadata access
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
// PEImage is always unique on CoreCLR so a simple pointer check is sufficient
_ASSERTE(m_bInHashMap || GetPath().IsEmpty());
_ASSERTE(pImage->m_bInHashMap || pImage->GetPath().IsEmpty());
return dac_cast<TADDR>(pImage) == dac_cast<TADDR>(this);
-#else // FEATURE_CORECLR
- if (pImage == this)
- return TRUE;
-
- if (GetPath().IsEmpty())
- {
-#ifdef FEATURE_FUSION
- if (m_fIsIStream && pImage->m_fIsIStream)
- {
- return (m_StreamAsmId == pImage->m_StreamAsmId) && (m_dwStreamModuleId == pImage->m_dwStreamModuleId);
- }
-#endif
-
- return FALSE;
- }
- else
- {
- BOOL ret = FALSE;
- HRESULT hr;
- EX_TRY
- {
- if (PathEquals(GetPath(), pImage->GetPath()))
- ret = TRUE;
- }
- EX_CATCH_HRESULT(hr); //<TODO>ignores failure!</TODO>
- return ret;
- }
-#endif // FEATURE_CORECLR
}
-#ifndef FEATURE_CORECLR
-void PEImage::ComputeHash(ALG_ID algorithm, SBuffer &result)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- PRECONDITION(CheckStartup());
- PRECONDITION(CheckValue(result));
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- PEImageLayoutHolder pview(GetLayout(PEImageLayout::LAYOUT_FLAT,PEImage::LAYOUT_CREATEIFNEEDED));
-
- if (algorithm == CALG_SHA1)
- {
- SHA1Hash hasher;
- hasher.AddData((BYTE *) pview->GetBase(), pview->GetSize());
- result.Set(hasher.GetHash(), SHA1_HASH_SIZE);
- return;
- }
-
- DWORD size = 0;
- if(!StrongNameHashSize(algorithm, &size))
- {
- ThrowHR(StrongNameErrorInfo());
- }
-
- BYTE *buffer = result.OpenRawBuffer(size);
-
- DWORD hashSize;
- IfFailThrow(GetHashFromBlob((BYTE *) pview->GetBase(), pview->GetSize(), &algorithm, buffer, size, &hashSize));
-
- _ASSERTE(size == hashSize);
-
- result.CloseRawBuffer(hashSize);
-}
-
-CHECK PEImage::CheckHash(ALG_ID algorithm, const void *pbHash, COUNT_T cbHash)
-{
- CONTRACT_CHECK
- {
- INSTANCE_CHECK;
- PRECONDITION(CheckStartup());
- INSTANCE_CHECK;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACT_CHECK_END;
-
- StackSBuffer hash;
- ComputeHash(algorithm, hash);
-
- CHECK(hash.Equals((const BYTE *) pbHash, cbHash));
-
- CHECK_OK;
-}
-#endif // FEATURE_CORECLR
IMDInternalImport* PEImage::GetMDImport()
{
m_bIsTrustedNativeImage(FALSE),
m_bIsNativeImageInstall(FALSE),
m_bPassiveDomainOnly(FALSE),
-#ifndef FEATURE_CORECLR
- m_fReportedToUsageLog(FALSE),
-#endif // !FEATURE_CORECLR
m_bInHashMap(FALSE),
#ifdef METADATATRACKER_DATA
m_pMDTracker(NULL),
m_dwPEKind(0),
m_dwMachine(0),
m_fCachedKindAndMachine(FALSE)
-#ifdef FEATURE_APTCA
- , m_fMayBeConditionalAptca(TRUE)
-#endif // FEATURE_APTCA
#ifdef FEATURE_LAZY_COW_PAGES
,m_bAllocatedLazyCOWPages(FALSE)
#endif // FEATURE_LAZY_COW_PAGES
{
PEImageLayout * pLoadLayout = NULL;
-#ifdef FEATURE_CORECLR
if (m_bIsTrustedNativeImage || IsFile())
{
// For CoreCLR, try to load all files via LoadLibrary first. If LoadLibrary did not work, retry using
// regular mapping - but not for native images.
pLoadLayout = PEImageLayout::Load(this, TRUE /* bNTSafeLoad */, m_bIsTrustedNativeImage /* bThrowOnError */);
}
-#else
- if (m_bIsTrustedNativeImage)
- {
- pLoadLayout = PEImageLayout::Load(this, FALSE);
- }
- else if (m_bIsNativeImageInstall)
- {
- // When ESB (extended secure boot) is enabled, a native image that is being installed can
- // only be loaded flat.
- PEImageLayout* pFlatLayout=PEImageLayout::LoadFlat(GetFileHandle(),this);
- SetLayout(IMAGE_FLAT,pFlatLayout);
- pLoadLayout = new ConvertedImageLayout(pFlatLayout);
- }
-#ifdef FEATURE_READYTORUN
- else if (ReadyToRunInfo::IsReadyToRunEnabled() && IsFile())
- {
- pLoadLayout = PEImageLayout::Load(this, FALSE, FALSE);
- }
-#endif // FEATURE_READYTORUN
-
-#endif // FEATURE_CORECLR
if (pLoadLayout != NULL)
{
// since LoadLibrary is needed if we are to actually load code.
if (pLayout->HasCorHeader() && pLayout->IsILOnly())
{
-#ifdef FEATURE_CORECLR
// For CoreCLR, IL only images will always be mapped. We also dont bother doing the conversion of PE header on 64bit,
// as done below for the desktop case, as there is no appcompat burden for CoreCLR on 64bit to have that conversion done.
fMarkAnyCpuImageAsLoaded = true;
-#else // !FEATURE_CORECLR
-
-#ifdef _WIN64
- // When attempting to load an assembly using LoadLibrary on x64,
- // the execution will go via the shell-shim that will try to determine
- // if the assembly is ILOnly with Pe32 header (i.e. built as anycpu). If it is,
- // it will convert the in-memory PEheader of the image to be PE32+ (i.e. mark it as 64bit image).
- //
- // Since we are trying to avoid mapping twice for ILOnly images by simply memory mapping them,
- // we should emulate the shell-shim behaviour for 64bit. This will allow inproc-components (e.g. ASP.NET),
- // which check for Pe32+ header, to continue working as expected.
- //
- // If we fail for some reason to change the header, in retail build, we will simply fallback to the double-loading behaviour without
- // any functional problems.
- if (pLayout->Has32BitNTHeaders())
- {
- fMarkAnyCpuImageAsLoaded = pLayout->ConvertILOnlyPE32ToPE64();
- }
- else
- {
- // Before assuming that PE32+ file can be loaded, confirm that
- // it is the expected machine type. This will ensure AMD64 does not load ARM64 or IA64 assemblies (and likewise).
- // If the machine type does not match, the Loader will fail the load at a later point.
- if (pLayout->GetMachine() == IMAGE_FILE_MACHINE_NATIVE)
- {
- fMarkAnyCpuImageAsLoaded = true; // PE32+ (aka native 64bit) binaries dont require any extra processing.
- }
- }
-#else // !_WIN64
- // Why can we not blindly assume that on 32bit OS, image should always be loaded? This is because it is possible to load
- // PE32+ image and map it to the 32bit process in WOW64.
- if (pLayout->Has32BitNTHeaders())
- fMarkAnyCpuImageAsLoaded = true;
-#endif // _WIN64
-
-#endif // FEATURE_CORECLR
}
pLayout.SuppressRelease();
}
else
{
-#ifdef FEATURE_CORECLR
if(m_pLayouts[IMAGE_LOADED]==NULL)
SetLayout(IMAGE_LOADED,PEImageLayout::Load(this,TRUE));
-#else
-
- //as part of Load() call we may initialize loaded image in DllMain
- //so we have to leave the lock and be prepared that when PEImageLayout::Load returns
- //m_pLayouts[IMAGE_LOADED] is set to something else
- lock.Release();
-
- FileHandleHolder pProtect=GetProtectingFileHandle(FALSE);
-
- // if the image is IL-only, try to load it in the safe manner
-
- // using the Internal function here because we are under the writer lock
- PEImageLayoutHolder pLayout=GetLayoutInternal(PEImageLayout::LAYOUT_ANY,0);
- BOOL bPreferSafeLoad=(pLayout && pLayout->IsILOnly());
-
- // Always use safe load during NGen to avoid running unmanaged code in IJW assemblies
- if (IsCompilationProcess())
- bPreferSafeLoad = TRUE;
-
- PEImageLayoutHolder pLoaded(PEImageLayout::Load(this,bPreferSafeLoad));
-
- lock.Acquire();
-
- if(m_pLayouts[IMAGE_LOADED]==NULL)
- SetLayout(IMAGE_LOADED,pLoaded.Extract());
-
-#endif // FEATURE_CORECLR
}
}
void VerifyIsAssembly();
void VerifyIsNIAssembly();
-#ifndef FEATURE_CORECLR
- BOOL IsReportedToUsageLog();
- void SetReportedToUsageLog();
-#ifndef DACCESS_COMPILE
- HRESULT GetILFingerprint(IILFingerprint **ppFingerprint);
-#endif //!DACCESS_COMPILE
-#endif //!FEATURE_CORECLR
static void GetAll(SArray<PEImage*> &images);
BOOL m_bIsTrustedNativeImage;
BOOL m_bIsNativeImageInstall;
BOOL m_bPassiveDomainOnly;
-#ifndef FEATURE_CORECLR
- BOOL m_fReportedToUsageLog;
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_LAZY_COW_PAGES
BOOL m_bAllocatedLazyCOWPages;
#endif // FEATURE_LAZY_COW_PAGES
DWORD m_dwMachine;
BOOL m_fCachedKindAndMachine;
-#ifdef FEATURE_APTCA
- BOOL m_fMayBeConditionalAptca;
-#endif // FEATURE_APTCA
#ifdef FEATURE_FUSION
PEFingerprint *m_pILFingerprint; // has to be the real type (as opposed to an interface) so we can delete it
PEKIND GetFusionProcessorArchitecture();
#endif
-#ifdef FEATURE_APTCA
- inline BOOL MayBeConditionalAptca();
- inline void SetIsNotConditionalAptca();
-#endif // FEATURE_APTCA
};
FORCEINLINE void PEImageRelease(PEImage *i)
#ifndef DACCESS_COMPILE
-#if !defined(FEATURE_CORECLR)
-inline const HRESULT PEImage::VerifyStrongName(DWORD* verifyOutputFlags)
-{
- WRAPPER_NO_CONTRACT;
- _ASSERTE(verifyOutputFlags);
- if (m_bSignatureInfoCached)
- {
- if (SUCCEEDED(m_hrSignatureInfoStatus))
- *verifyOutputFlags=m_dwSignatureInfo;
- return m_hrSignatureInfoStatus;
- }
-
- BOOL result = FALSE;
-
- PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_FLAT,0));
- if(pLayout!=NULL)
- {
- result = StrongNameSignatureVerificationFromImage((BYTE *) pLayout->GetBase(), pLayout->GetSize(),
- SN_INFLAG_INSTALL|SN_INFLAG_ALL_ACCESS,
- verifyOutputFlags);
- }
- else
- {
- CONSISTENCY_CHECK(!GetPath().IsEmpty());
- _ASSERTE(IsFileLocked());
- result = StrongNameSignatureVerification(GetPath(),
- SN_INFLAG_INSTALL|SN_INFLAG_ALL_ACCESS|SN_INFLAG_RUNTIME,
- verifyOutputFlags);
- }
-
- HRESULT hr=result?S_OK: StrongNameErrorInfo();
-
- if (SUCCEEDED(hr) || !Exception::IsTransient(hr))
- {
- m_hrSignatureInfoStatus=hr;
- m_dwSignatureInfo=*verifyOutputFlags;
- m_bSignatureInfoCached=TRUE;
- }
- return hr;
-}
-#endif // !FEATURE_CORECLR
#endif // !DACCESS_COMPILE
}
#ifndef DACCESS_COMPILE
-#if !defined(FEATURE_CORECLR)
-/*static*/
-inline PTR_PEImage PEImage::FindByLongPath(LPCWSTR pPath)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(s_hashLock.OwnedByCurrentThread());
- }
- CONTRACTL_END;
-
- PathString sLongPath;
- COUNT_T nLen = WszGetLongPathName(pPath, sLongPath);
-
- // Check for any kind of error other than an insufficient buffer result.
- if (nLen == 0)
- {
- HRESULT hr=HRESULT_FROM_WIN32(GetLastError());
- if(Exception::IsTransient(hr))
- ThrowHR(hr);
- return (PEImage*)INVALIDENTRY;
- }
- return FindByPath(sLongPath.GetUnicode());
-}
-
-/*static*/
-inline PTR_PEImage PEImage::FindByShortPath(LPCWSTR pPath)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(s_hashLock.OwnedByCurrentThread());
- }
- CONTRACTL_END;
-
- PathString sShortPath;
- COUNT_T nLen = WszGetShortPathName(pPath, sShortPath);
-
- // Check for any kind of error other than an insufficient buffer result.
- if (nLen == 0)
- {
- HRESULT hr=HRESULT_FROM_WIN32(GetLastError());
- if(Exception::IsTransient(hr))
- ThrowHR(hr);
- return (PEImage*)INVALIDENTRY;
- }
- return FindByPath(sShortPath.GetUnicode());
-}
-#endif // !FEATURE_CORECLR
/*static*/
inline PTR_PEImage PEImage::FindByPath(LPCWSTR pPath)
PEImage* found = FindByPath(pPath);
-#if !defined(FEATURE_CORECLR)
- if(found == (PEImage*) INVALIDENTRY && (flags & MDInternalImport_CheckLongPath))
- found=FindByLongPath(pPath);
-
- if(found == (PEImage*) INVALIDENTRY && (flags & MDInternalImport_CheckShortPath))
- found=FindByShortPath(pPath);
-#endif
if (found == (PEImage*) INVALIDENTRY)
{
*pdwMachine = m_dwMachine;
}
-#ifdef FEATURE_APTCA
-inline BOOL PEImage::MayBeConditionalAptca()
-{
- LIMITED_METHOD_CONTRACT;
- return m_fMayBeConditionalAptca;
-}
-
-inline void PEImage::SetIsNotConditionalAptca()
-{
- LIMITED_METHOD_CONTRACT;
- m_fMayBeConditionalAptca = FALSE;
-}
-#endif // FEATURE_APTCA
-#ifndef FEATURE_CORECLR
-inline BOOL PEImage::IsReportedToUsageLog()
-{
- LIMITED_METHOD_CONTRACT;
- return m_fReportedToUsageLog;
-}
-
-inline void PEImage::SetReportedToUsageLog()
-{
- LIMITED_METHOD_CONTRACT;
- m_fReportedToUsageLog = TRUE;
-}
-#endif // !FEATURE_CORECLR
#ifndef DACCESS_COMPILE
inline void PEImage::AllocateLazyCOWPages()
}
#endif // FEATURE_PREJIT
-#ifndef FEATURE_CORECLR
-// Event Tracing for Windows is used to log data for performance and functional testing purposes.
-// The events in this structure are used to measure the time taken by PE image mapping. This is useful to reliably measure the
-// performance of the assembly loader by subtracting the time taken by the possibly I/O-intensive work of PE image mapping.
-struct ETWLoaderMappingPhaseHolder { // Special-purpose holder structure to ensure the LoaderMappingPhaseEnd ETW event is fired when returning from a function.
- StackSString ETWCodeBase;
- DWORD _dwAppDomainId;
- BOOL initialized;
-
- ETWLoaderMappingPhaseHolder(){
- LIMITED_METHOD_CONTRACT;
- _dwAppDomainId = ETWAppDomainIdNotAvailable;
- initialized = FALSE;
- }
-
- void Init(DWORD dwAppDomainId, SString wszCodeBase) {
- _dwAppDomainId = dwAppDomainId;
-
- EX_TRY
- {
- ETWCodeBase.Append(wszCodeBase);
- ETWCodeBase.Normalize(); // Ensures that the later cast to LPCWSTR does not throw.
- }
- EX_CATCH
- {
- ETWCodeBase.Clear();
- }
- EX_END_CATCH(RethrowTransientExceptions)
-
- FireEtwLoaderMappingPhaseStart(_dwAppDomainId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, ETWCodeBase.IsEmpty() ? NULL : (LPCWSTR)ETWCodeBase, NULL, GetClrInstanceId());
-
- initialized = TRUE;
- }
-
- ~ETWLoaderMappingPhaseHolder() {
- if (initialized) {
- FireEtwLoaderMappingPhaseEnd(_dwAppDomainId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, ETWCodeBase.IsEmpty() ? NULL : (LPCWSTR)ETWCodeBase, NULL, GetClrInstanceId());
- }
- }
-};
-#endif // FEATURE_CORECLR
RawImageLayout::RawImageLayout(const void *flat, COUNT_T size,PEImage* pOwner)
{
PEFingerprintVerificationHolder verifyHolder(pOwner); // Do not remove: This holder ensures the IL file hasn't changed since the runtime started making assumptions about it.
-#ifndef FEATURE_CORECLR
- ETWLoaderMappingPhaseHolder loaderMappingPhaseHolder;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
- loaderMappingPhaseHolder.Init(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, GetPath());
- }
-#endif // FEATURE_CORECLR
if (size)
{
PEFingerprintVerificationHolder verifyHolder(pOwner); // Do not remove: This holder ensures the IL file hasn't changed since the runtime started making assumptions about it.
-#ifndef FEATURE_CORECLR
- ETWLoaderMappingPhaseHolder loaderMappingPhaseHolder;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
- loaderMappingPhaseHolder.Init(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, GetPath());
- }
-#endif // FEATURE_CORECLR
if (bTakeOwnership)
{
PEFingerprintVerificationHolder verifyHolder(source->m_pOwner); // Do not remove: This holder ensures the IL file hasn't changed since the runtime started making assumptions about it.
-#ifndef FEATURE_CORECLR
- ETWLoaderMappingPhaseHolder loaderMappingPhaseHolder;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
- loaderMappingPhaseHolder.Init(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, GetPath());
- }
-#endif // FEATURE_CORECLR
if (!source->HasNTHeaders())
EEFileLoadException::Throw(GetPath(), COR_E_BADIMAGEFORMAT);
#ifndef FEATURE_PAL
-#ifndef FEATURE_CORECLR
- ETWLoaderMappingPhaseHolder loaderMappingPhaseHolder;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
- loaderMappingPhaseHolder.Init(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, GetPath());
- }
-#endif // FEATURE_CORECLR
// Let OS map file for us
if (m_FileMap == NULL)
{
#ifndef CROSSGEN_COMPILE
-#ifdef FEATURE_CORECLR
// There is no reflection-only load on CoreCLR and so we can always throw an error here.
// It is important on Windows Phone. All assemblies that we load must have SEC_IMAGE set
// so that the OS can perform signature verification.
ThrowLastError();
-#else // FEATURE_CORECLR
-
- // We need to ensure any signature validation errors are caught if Extended Secure Boot (ESB) is on.
- // Also, we have to always throw here during NGen to ensure that the signature validation is never skipped.
- if (GetLastError() != ERROR_BAD_EXE_FORMAT || IsCompilationProcess())
- {
- ThrowLastError();
- }
-
-#endif // FEATURE_CORECLR
#endif // CROSSGEN_COMPILE
return;
PEFingerprintVerificationHolder verifyHolder(pOwner); // Do not remove: This holder ensures the IL file hasn't changed since the runtime started making assumptions about it.
-#ifndef FEATURE_CORECLR
- ETWLoaderMappingPhaseHolder loaderMappingPhaseHolder;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
- loaderMappingPhaseHolder.Init(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, GetPath());
- }
-#endif // FEATURE_CORECLR
DWORD dwFlags = GetLoadWithAlteredSearchPathFlag();
if (bNTSafeLoad)
PEFingerprintVerificationHolder verifyHolder(pOwner); // Do not remove: This holder ensures the IL file hasn't changed since the runtime started making assumptions about it.
-#ifndef FEATURE_CORECLR
- ETWLoaderMappingPhaseHolder loaderMappingPhaseHolder;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
- loaderMappingPhaseHolder.Init(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, GetPath());
- }
-#endif // FEATURE_CORECLR
COUNT_T size = SafeGetFileSize(hFile, NULL);
if (size == 0xffffffff && GetLastError() != NOERROR)
PEFingerprintVerificationHolder verifyHolder(pOwner); // Do not remove: This holder ensures the IL file hasn't changed since the runtime started making assumptions about it.
-#ifndef FEATURE_CORECLR
- ETWLoaderMappingPhaseHolder loaderMappingPhaseHolder;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
- loaderMappingPhaseHolder.Init(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, GetPath());
- }
-#endif // FEATURE_CORECLR
STATSTG statStg;
IfFailThrow(pIStream->Stat(&statStg, STATFLAG_NONAME));
#include "profilinghelper.inl"
#include "eemessagebox.h"
-#if defined(FEATURE_PROFAPI_EVENT_LOGGING) && !defined(FEATURE_CORECLR)
-#include <eventmsg.h>
-#endif // FEATURE_PROFAPI_EVENT_LOGGING) && !FEATURE_CORECLR
#ifdef FEATURE_PROFAPI_ATTACH_DETACH
#include "profattach.h"
AppendSupplementaryInformation(iStringResourceID, &messageToLog);
-#if defined(FEATURE_CORECLR)
// CoreCLR on Windows ouputs debug strings for diagnostic messages.
WszOutputDebugString(messageToLog);
-#else
- // Get the user SID for the current process, so it can be provided to the event
- // logging API, which will then fill out the "User" field in the event log entry. If
- // this fails, that's not fatal. We can just pass NULL for the PSID, and the "User"
- // field will be left blank.
- PSID psid = NULL;
- HRESULT hr = GetCurrentProcessUserSid(&psid);
- if (FAILED(hr))
- {
- // No biggie. Just pass in a NULL psid, and the User field will be empty
- _ASSERTE(psid == NULL);
- }
-
- // On desktop CLR builds, the profiling API uses the event log for end-user-friendly
- // diagnostic messages.
- ReportEventCLR(wEventType, // wType
- 0, // wCategory
- COR_Profiler, // dwEventID
- psid, // lpUserSid
- &messageToLog); // uh duh
-#endif // FEATURE_CORECLR
#endif // FEATURE_PROFAPI_EVENT_LOGGING
}
// Find out if profiling is enabled
DWORD fProfEnabled = 0;
-#ifdef FEATURE_CORECLR
fProfEnabled = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CORECLR_ENABLE_PROFILING);
-#else //FEATURE_CORECLR
- fProfEnabled = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_COR_ENABLE_PROFILING);
-#endif //FEATURE_CORECLR
// If profiling is not enabled, return.
if (fProfEnabled == 0)
NewArrayHolder<WCHAR> wszClsid(NULL);
NewArrayHolder<WCHAR> wszProfilerDLL(NULL);
-#ifdef FEATURE_CORECLR
IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CORECLR_PROFILER, &wszClsid));
#if defined(_TARGET_X86_)
{
IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CORECLR_PROFILER_PATH, &wszProfilerDLL));
}
-#else // FEATURE_CORECLR
- IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_COR_PROFILER, &wszClsid));
-
-#if defined(_TARGET_X86_)
- IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_COR_PROFILER_PATH_32, &wszProfilerDLL));
-#elif defined(_TARGET_AMD64_)
- IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_COR_PROFILER_PATH_64, &wszProfilerDLL));
-#endif
- if(wszProfilerDLL == NULL)
- {
- IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_COR_PROFILER_PATH, &wszProfilerDLL));
- }
-#endif // FEATURE_CORECLR
// If the environment variable doesn't exist, profiling is not enabled.
if (wszClsid == NULL)
if (!pMethodDesc ->IsRestored())
return CORPROF_E_DATAINCOMPLETE;
-#ifdef FEATURE_CORECLR
if (g_pDebugInterface == NULL)
{
return CORPROF_E_DEBUGGING_DISABLED;
}
-#else
- // g_pDebugInterface is initialized on startup on desktop CLR, regardless of whether a debugger
- // or profiler is loaded. So it should always be available.
- _ASSERTE(g_pDebugInterface != NULL);
-#endif // FEATURE_CORECLR
COR_IL_MAP * rgNewILMapEntries = new (nothrow) COR_IL_MAP[cILMapEntries];
return E_INVALIDARG;
}
-#ifdef FEATURE_CORECLR
if (g_pDebugInterface == NULL)
{
return CORPROF_E_DEBUGGING_DISABLED;
}
-#else
- // g_pDebugInterface is initialized on startup on desktop CLR, regardless of whether a debugger
- // or profiler is loaded. So it should always be available.
- _ASSERTE(g_pDebugInterface != NULL);
-#endif // FEATURE_CORECLR
return (g_pDebugInterface->GetILToNativeMapping(pMD, cMap, pcMap, map));
#else
if (pRuntimeType != NULL)
{
-#ifdef FEATURE_CORECLR
*pRuntimeType = COR_PRF_CORE_CLR;
-#else // FEATURE_CORECLR
- *pRuntimeType = COR_PRF_DESKTOP_CLR;
-#endif // FEATURE_CORECLR
}
if (pMajorVersion != NULL)
if (!pLayout->IsNativeMachineFormat())
{
-#ifdef FEATURE_CORECLR
// For CoreCLR, be strict about disallowing machine mismatches.
COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
-#else
- DoLog("Ready to Run disabled - mismatched architecture");
- return NULL;
-#endif
}
#ifdef FEATURE_NATIVE_IMAGE_GENERATION
m_pOnDiskEmitter = pOnDiskEmitter;
}
-#ifndef FEATURE_CORECLR
- //HRESULT EnsureCeeFileGenCreated(DWORD corhFlags = COMIMAGE_FLAGS_ILONLY, DWORD peFlags = ICEE_CREATE_FILE_PURE_IL);
- HRESULT EnsureCeeFileGenCreated(DWORD corhFlags, DWORD peFlags);
- HRESULT DestroyCeeFileGen();
-#endif
~RefClassWriter();
};
}
CONTRACTL_END;
-#ifndef FEATURE_CORECLR
- // Security checks are expensive as they involve stack walking. Avoid them if we can.
- // In immersive we don't allow private reflection to framework code. So we need to perform
- // the access check even if all the domains on the stack are fully trusted.
- if (Security::AllDomainsOnStackFullyTrusted() && !AppX::IsAppXProcess())
- return;
-#endif
REFLECTCLASSBASEREF refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
bool targetRemoted = FALSE;
-#ifndef FEATURE_CORECLR
- targetRemoted = targetObj != NULL && InvokeUtil::IsTargetRemoted(pFieldDesc, targetObj->GetMethodTable());
-#endif //FEATURE_CORECLR
RefSecContext sCtx(InvokeUtil::GetInvocationAccessCheckType(targetRemoted));
if (!securityOff)
{
-#ifndef FEATURE_CORECLR
- // Security checks are expensive as they involve stack walking. Avoid them if we can.
- // In immersive we don't allow private reflection to framework code. So we need to perform
- // the access check even if all the domains on the stack are fully trusted.
- if (Security::AllDomainsOnStackFullyTrusted() && !AppX::IsAppXProcess())
- {
- bNeedAccessCheck = false;
- }
- else
-#endif //FEATURE_CORECLR
{
// Public critical types cannot be accessed by transparent callers
bNeedAccessCheck = !pVMT->IsExternallyVisible() || Security::TypeRequiresTransparencyCheck(pVMT);
}
FCIMPLEND
-#ifndef FEATURE_CORECLR
-
-// Can not inline this function.
-#ifdef _MSC_VER
-__declspec(noinline)
-#endif
-void PerformSecurityCheckHelper(Object *targetUnsafe, MethodDesc *pMeth, MethodTable* pParentMT, DWORD dwFlags)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
-
- PRECONDITION(CheckPointer(pMeth));
- }
- CONTRACTL_END;
-
- OBJECTREF target (targetUnsafe);
- GCPROTECT_BEGIN (target);
- FrameWithCookie<DebuggerSecurityCodeMarkFrame> __dbgSecFrame;
-
- bool targetRemoted = false;
-
-#ifndef FEATURE_CORECLR
- targetRemoted = target != NULL && InvokeUtil::IsTargetRemoted(pMeth, target->GetMethodTable());
-#endif //FEATURE_CORECLR
-
- RefSecContext sCtx(InvokeUtil::GetInvocationAccessCheckType(targetRemoted));
-
- MethodTable* pInstanceMT = NULL;
- if (target != NULL) {
- if (!target->GetTypeHandle().IsTypeDesc())
- pInstanceMT = target->GetTypeHandle().AsMethodTable();
- }
-
-#ifdef FEATURE_CORECLR
- if (dwFlags & (INVOCATION_FLAGS_RISKY_METHOD|INVOCATION_FLAGS_IS_DELEGATE_CTOR))
- {
- // On CoreCLR we assert that "dangerous" methods (see IsDangerousMethods) can only
- // be reflection-invoked by platform code (C or SC).
-
- // Also, for delegates, in desktop we used to demand unmanaged
- // code permission for this since it's hard to validate the target address.
- // Here we just restrict access to Critical code.
- MethodDesc *pCallerMD = sCtx.GetCallerMethod();
-
- if (pCallerMD && Security::IsMethodTransparent(pCallerMD))
- {
- ThrowMethodAccessException(pCallerMD, pMeth, FALSE, IDS_E_TRANSPARENT_REFLECTION);
- }
- }
-
- if (dwFlags & (INVOCATION_FLAGS_NEED_SECURITY|INVOCATION_FLAGS_CONSTRUCTOR_INVOKE))
-#endif
- {
-
- if (dwFlags & INVOCATION_FLAGS_CONSTRUCTOR_INVOKE)
- InvokeUtil::CanAccessMethod(pMeth,
- pParentMT,
- pInstanceMT,
- &sCtx,
- TRUE /*fCriticalToFullDemand*/);
- else
- InvokeUtil::CanAccessMethod(pMeth,
- pParentMT,
- pInstanceMT,
- &sCtx,
- TRUE /*fCriticalToFullDemand*/,
- (dwFlags & INVOCATION_FLAGS_IS_CTOR) != 0 /*checkSkipVer*/);
- }
-
- __dbgSecFrame.Pop();
- GCPROTECT_END();
-}
-
-FCIMPL4(void, ReflectionInvocation::PerformSecurityCheck, Object *target, MethodDesc *pMeth, ReflectClassBaseObject *pParentUNSAFE, DWORD dwFlags) {
- CONTRACTL {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(pMeth));
- }
- CONTRACTL_END;
-
-#ifndef FEATURE_CORECLR
- // Security checks are expensive as they involve stack walking. Avoid them if we can.
- // In immersive we don't allow private reflection to framework code. So we need to perform
- // the access check even if all the domains on the stack are fully trusted.
- if (Security::AllDomainsOnStackFullyTrusted() && !AppX::IsAppXProcess())
- return;
-#endif
-
- REFLECTCLASSBASEREF refParent = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pParentUNSAFE);
-
- HELPER_METHOD_FRAME_BEGIN_1(refParent);
- //CAUTION: PerformSecurityCheckHelper could trigger GC!
-
- TypeHandle parent = refParent != NULL ? refParent->GetType() : TypeHandle();
- PerformSecurityCheckHelper(target,pMeth,parent.GetMethodTable(),dwFlags);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-#endif // FEATURE_CORECLR
/****************************************************************************/
/* boxed Nullable<T> are represented as a boxed T, so there is no unboxed
GCPROTECT_BEGIN(targetException);
#if defined(_DEBUG) && !defined(FEATURE_PAL)
-#ifdef FEATURE_CORECLR
if (IsWatsonEnabled())
-#endif // FEATURE_CORECLR
{
if (!CLRException::IsPreallocatedExceptionObject(targetException))
{
OBJECTREF except = InvokeUtil::CreateTargetExcept(&targetException);
#ifndef FEATURE_PAL
-#ifdef FEATURE_CORECLR
if (IsWatsonEnabled())
-#endif // FEATURE_CORECLR
{
struct
{
bool targetRemoted = false;
-#ifndef FEATURE_CORECLR
- targetRemoted = !targetType.IsNull() && InvokeUtil::IsTargetRemoted(pField, targetType.AsMethodTable());
-#endif //FEATURE_CORECLR
RefSecContext sCtx(InvokeUtil::GetInvocationAccessCheckType(targetRemoted));
// security and consistency checks
bool targetRemoted = false;
-#ifndef FEATURE_CORECLR
- targetRemoted = targetType.IsNull() && InvokeUtil::IsTargetRemoted(pField, targetType.AsMethodTable());
-#endif //FEATURE_CORECLR
RefSecContext sCtx(InvokeUtil::GetInvocationAccessCheckType(targetRemoted));
HELPER_METHOD_FRAME_BEGIN_1(refType);
// We perform the access check only on CoreCLR for backward compatibility.
-#ifdef FEATURE_CORECLR
RefSecContext sCtx(InvokeUtil::GetInvocationAccessCheckType());
InvokeUtil::CanAccessClass(&sCtx, pMT);
-#endif //FEATURE_CORECLR
pMT->CheckRestore();
pMT->EnsureInstanceActive();
}
FCIMPLEND
-#ifndef FEATURE_CORECLR
-// This method triggers a given method to be jitted
-FCIMPL3(void, ReflectionInvocation::PrepareMethod, ReflectMethodObject* pMethodUNSAFE, TypeHandle *pInstantiation, UINT32 cInstantiation)
-{
- CONTRACTL {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(pMethodUNSAFE, NULL_OK));
- PRECONDITION(CheckPointer(pInstantiation, NULL_OK));
- }
- CONTRACTL_END;
-
- REFLECTMETHODREF refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
-
- if (refMethod == NULL)
- FCThrowArgumentVoidEx(kArgumentException, NULL, W("InvalidOperation_HandleIsNotInitialized"));
-
- MethodDesc *pMD = refMethod->GetMethod();
-
- HELPER_METHOD_FRAME_BEGIN_1(refMethod);
-
- if (pMD->IsAbstract())
- COMPlusThrowArgumentNull(W("method"), W("Argument_CannotPrepareAbstract"));
-
- pMD->CheckRestore();
-
- MethodTable * pExactMT = pMD->GetMethodTable();
- if (pInstantiation != NULL)
- {
- // We were handed an instantiation, check that the method expects it and the right number of types has been provided (the
- // caller supplies one array containing the class instantiation immediately followed by the method instantiation).
- if (cInstantiation != (pMD->GetNumGenericMethodArgs() + pMD->GetNumGenericClassArgs()))
- COMPlusThrow(kArgumentException, W("Argument_InvalidGenericInstantiation"));
-
- // We need to find the actual class and/or method instantiations, even though we've been passed them. This is an issue of
- // lifetime -- the instantiation passed in will go away at some point whereas preparation of the method has the potential to
- // persist a copy of the instantiation pointer. By finding the actual instantiation we get a stable pointer whose lifetime
- // is at least as long as the data generated by preparation.
-
- // Check we've got a reasonable looking instantiation.
- if (!Generics::CheckInstantiation(Instantiation(pInstantiation, cInstantiation)))
- COMPlusThrow(kArgumentException, W("Argument_InvalidGenericInstantiation"));
- for (ULONG i = 0; i < cInstantiation; i++)
- if (pInstantiation[i].ContainsGenericVariables())
- COMPlusThrow(kArgumentException, W("Argument_InvalidGenericInstantiation"));
-
- // Load the exact type of the method if it needs to be instantiated (because it's a generic type definition, e.g. C<T>, or a
- // shared type instantiation, e.g. C<Object>).
- if (pExactMT->IsGenericTypeDefinition() || pExactMT->IsSharedByGenericInstantiations())
- {
- TypeHandle thExactType = ClassLoader::LoadGenericInstantiationThrowing(pMD->GetModule(),
- pMD->GetMethodTable()->GetCl(),
- Instantiation(pInstantiation, pMD->GetNumGenericClassArgs()));
- pExactMT = thExactType.AsMethodTable();
- }
-
- // As for the class we might need to find a method desc with an exact instantiation if the one we have is too vague.
- // Note: IsGenericMethodDefinition implies ContainsGenericVariables so there's no need to check it separately.
- if (pMD->IsSharedByGenericInstantiations() || pMD->ContainsGenericVariables())
- pMD = MethodDesc::FindOrCreateAssociatedMethodDesc(pMD,
- pExactMT,
- FALSE,
- Instantiation(&pInstantiation[pMD->GetNumGenericClassArgs()], pMD->GetNumGenericMethodArgs()),
- FALSE);
- }
- else
- {
- // No instantiation provided, the method better not be expecting one.
-
- // Methods that are generic definitions (e.g. C.Foo<U>) and those that are shared (e.g. C<Object>.Foo, C.Foo<Object>) need
- // extra instantiation data.
- // Note: IsGenericMethodDefinition implies ContainsGenericVariables so there's no need to check it separately.
- if (pMD->IsSharedByGenericInstantiations() || pMD->ContainsGenericVariables())
- COMPlusThrow(kArgumentException, W("Argument_InvalidGenericInstantiation"));
-
- // The rest of the cases (non-generics related methods, instantiating stubs, methods instantiated over non-shared types
- // etc.) should be able to provide their instantiation for us as necessary.
- }
-
- // Go prepare the method at the specified instantiation.
- PrepareMethodDesc(pMD, pExactMT->GetInstantiation(), pMD->GetMethodInstantiation());
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-// This method triggers a given delegate to be prepared. This involves preparing the
-// delegate's Invoke method and preparing the target of that Invoke. In the case of
-// a multi-cast delegate, we rely on the fact that each individual component was prepared
-// prior to the Combine. If our event sinks perform the Combine, this is always true.
-// If the client calls Combine himself, he is responsible for his own preparation.
-FCIMPL1(void, ReflectionInvocation::PrepareDelegate, Object* delegateUNSAFE)
-{
- CONTRACTL {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(delegateUNSAFE, NULL_OK));
- }
- CONTRACTL_END;
-
- if (delegateUNSAFE == NULL)
- return;
-
- OBJECTREF delegate = ObjectToOBJECTREF(delegateUNSAFE);
- HELPER_METHOD_FRAME_BEGIN_1(delegate);
-
- PrepareDelegateHelper(&delegate, FALSE);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
FCIMPL1(void, ReflectionInvocation::PrepareContractedDelegate, Object * delegateUNSAFE)
{
static FCDECL1(void, RunClassConstructor, ReflectClassBaseObject *pTypeUNSAFE);
static FCDECL1(void, RunModuleConstructor, ReflectModuleBaseObject *pModuleUNSAFE);
-#ifndef FEATURE_CORECLR
- static FCDECL3(void, PrepareMethod, ReflectMethodObject* pMethodUNSAFE, TypeHandle *pInstantiation, UINT32 cInstantiation);
- static FCDECL1(void, PrepareDelegate, Object* delegateUNSAFE);
-#endif // !FEATURE_CORECLR
static FCDECL1(void, PrepareContractedDelegate, Object* delegateUNSAFE);
static FCDECL0(void, ProbeForSufficientStack);
static FCDECL0(void, EnsureSufficientExecutionStack);
return E_INVALIDARG;
}
-#ifdef FEATURE_CORECLR
if (g_pDebugInterface == NULL)
{
return CORPROF_E_DEBUGGING_DISABLED;
}
-#else
- // g_pDebugInterface is initialized on startup on desktop CLR, regardless of whether a debugger
- // or profiler is loaded. So it should always be available.
- _ASSERTE(g_pDebugInterface != NULL);
-#endif // FEATURE_CORECLR
// copy the il map and il map entries into the corresponding fields.
//
DEFINE_EXCEPTION(g_ReflectionNS, AmbiguousMatchException, false, COR_E_AMBIGUOUSMATCH)
-#ifdef FEATURE_CORECLR
// ApplicationException is removed in CoreCLR
#define kApplicationException kException
-#else
-DEFINE_EXCEPTION(g_SystemNS, ApplicationException, false, COR_E_APPLICATION)
-#endif // FEATURE_CORECLR
DEFINE_EXCEPTION(g_SystemNS, AppDomainUnloadedException, false, COR_E_APPDOMAINUNLOADED)
DEFINE_EXCEPTION(g_SystemNS, ArithmeticException, false, COR_E_ARITHMETIC)
META_E_BAD_SIGNATURE,
COR_E_LOADING_WINMD_REFERENCE_ASSEMBLY)
-#ifdef FEATURE_CORECLR
// CannotUnloadAppDomainException is removed in CoreCLR
#define kCannotUnloadAppDomainException kException
-#else
-DEFINE_EXCEPTION(g_SystemNS, CannotUnloadAppDomainException, false, COR_E_CANNOTUNLOADAPPDOMAIN)
-#endif // FEATURE_CORECLR
DEFINE_EXCEPTION(g_CodeContractsNS, ContractException, false, COR_E_CODECONTRACTFAILED)
#if defined(FEATURE_X509) || defined(FEATURE_CRYPTO)
DEFINE_EXCEPTION(g_CryptographyNS, CryptographicException, false, CORSEC_E_CRYPTO)
#endif // FEATURE_X509 || FEATURE_CRYPTO
-#ifndef FEATURE_CORECLR
-DEFINE_EXCEPTION(g_CryptographyNS, CryptographicUnexpectedOperationException, false, CORSEC_E_CRYPTO_UNEX_OPER)
-#endif // FEATURE_CORECLR
DEFINE_EXCEPTION(g_SystemNS, DataMisalignedException, false, COR_E_DATAMISALIGNED)
DEFINE_EXCEPTION(g_SecurityNS, VerificationException, false, COR_E_VERIFICATION)
-#ifdef FEATURE_CAS_POLICY
-DEFINE_EXCEPTION(g_PolicyNS, PolicyException, true, CORSEC_E_POLICY_EXCEPTION, CORSEC_E_NO_EXEC_PERM, CORSEC_E_MIN_GRANT_FAIL)
-DEFINE_EXCEPTION(g_SecurityNS, XmlSyntaxException, false, CORSEC_E_XMLSYNTAX)
-#endif // FEATURE_CAS_POLICY
DEFINE_EXCEPTION(g_InteropNS, COMException, false, E_FAIL)
DEFINE_EXCEPTION(g_InteropNS, ExternalException, false, E_FAIL)
DEFINE_EXCEPTION(g_SystemNS, OutOfMemoryException, false, E_OUTOFMEMORY, CTL_E_OUTOFMEMORY, STD_CTL_SCODE(31001))
-#ifdef FEATURE_CORECLR
DEFINE_EXCEPTION(g_SystemNS, CrossAppDomainMarshaledException, false, E_FAIL)
-#endif //FEATURE_CORECLR
#ifdef FEATURE_ISOSTORE
DEFINE_EXCEPTION(g_IsolatedStorageNS, IsolatedStorageException, true,
StackSString ssServer;
if (FAILED(Clr::Util::Com::FindServerUsingCLSID(m_rclsid, ssServer)))
{
-#ifndef FEATURE_CORECLR
- // If there is no server entry, then that implies the CLSID could be implemented by CLR.DLL itself,
- // if the CLSID is one of the special ones implemented by the CLR. We need to check against the
- // specific list of CLSIDs here because CLR.DLL-implemented CLSIDs and managed class-implemented
- // CLSIDs look the same until you start interating the subkeys. For now, the set of CLSIDs implemented
- // by CLR.DLL is a short and tractable list, but at some point it might become worthwhile to move over
- // to the more generalized solution of looking for the entries that identify when the CLSID is
- // implemented by a managed type to avoid having to maintain the hardcoded list.
- if (IsClrHostedLegacyComObject(m_rclsid))
- {
- PDllGetClassObject pFN = NULL;
- hr = g_pCLRRuntime->GetProcAddress("DllGetClassObjectInternal", reinterpret_cast<void**>(&pFN));
-
- if (FAILED(hr))
- hr = g_pCLRRuntime->GetProcAddress("DllGetClassObject", reinterpret_cast<void**>(&pFN));
-
- if (SUCCEEDED(hr))
- hr = pFN(m_rclsid, IID_IClassFactory, (void**)&pClassFactory);
- }
-#endif
}
else
{
-#ifndef FEATURE_CORECLR
- // @CORESYSTODO: ?
-
- // There is a SxS DLL that implements this CLSID.
- // NOTE: It is standard practise for RCWs and P/Invokes to leak their module handles,
- // as there is no automated mechanism for the runtime to call CanUnloadDllNow.
- HMODULE hServer = NULL;
- if (SUCCEEDED(hr = g_pCLRRuntime->LoadLibrary(ssServer.GetUnicode(), &hServer)))
- {
- PDllGetClassObject pFN = reinterpret_cast<PDllGetClassObject>(GetProcAddress(hServer, "DllGetClassObject"));
- if (pFN != NULL)
- {
- hr = pFN(m_rclsid, IID_IClassFactory, (void**)&pClassFactory);
- }
- else
- {
- hr = HRESULT_FROM_GetLastError();
- }
- }
-#endif
}
}
#endif // FEATURE_CLASSIC_COMINTEROP
// make sure it is on the right thread
IDispatch *RCW::GetIDispatch()
{
-#ifdef FEATURE_CORECLR
if (AppX::IsAppXProcess())
{
COMPlusThrow(kPlatformNotSupportedException, IDS_EE_ERROR_IDISPATCH);
}
-#endif // FEATURE_CORECLR
WRAPPER_NO_CONTRACT;
return (IDispatch *)GetWellKnownInterface(IID_IDispatch);
if (pItfMT == MscorlibBinder::GetExistingClass(CLASS__IENUMERABLE))
{
SafeComHolder<IDispatch> pDisp = NULL;
-#ifdef FEATURE_CORECLR
if (!AppX::IsAppXProcess())
-#endif // FEATURE_CORECLR
{
// Get the IDispatch on the current thread.
pDisp = GetIDispatch();
}
}
-#ifndef FEATURE_CORECLR
- if (pCallee->RequiresLinktimeCheck())
- {
- Module *pModule = refModule->GetModule();
- Security::LinktimeCheckMethod(pDecoratedModule->GetAssembly(), pCallee);
- }
-#endif // !FEATURE_CORECLR
}
HELPER_METHOD_FRAME_END();
}
-#ifndef FEATURE_CORECLR
-FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::IsEquivalentTo, ReflectClassBaseObject *rtType1UNSAFE, ReflectClassBaseObject *rtType2UNSAFE)
-{
- FCALL_CONTRACT;
-
- BOOL bResult = FALSE;
-
- REFLECTCLASSBASEREF rtType1 = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(rtType1UNSAFE);
- REFLECTCLASSBASEREF rtType2 = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(rtType2UNSAFE);
-
- HELPER_METHOD_FRAME_BEGIN_RET_2(rtType1, rtType2);
- if (rtType1 == NULL)
- COMPlusThrowArgumentNull(W("rtType1"));
- if (rtType2 == NULL)
- COMPlusThrowArgumentNull(W("rtType2"));
-
- bResult = rtType1->GetType().IsEquivalentTo(rtType2->GetType());
- HELPER_METHOD_FRAME_END();
-
- FC_RETURN_BOOL(bResult);
-}
-FCIMPLEND
-
-FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsEquivalentType, ReflectClassBaseObject *rtTypeUNSAFE)
-{
- FCALL_CONTRACT;
-
- BOOL bResult = FALSE;
-
- TypeHandle typeHandle = rtTypeUNSAFE->GetType();
- if (!typeHandle.IsTypeDesc())
- bResult = typeHandle.AsMethodTable()->GetClass()->IsEquivalentType();
-
- FC_RETURN_BOOL(bResult);
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_COMINTEROP
FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsWindowsRuntimeObjectType, ReflectClassBaseObject *rtTypeUNSAFE)
}
FCIMPLEND
-#ifdef FEATURE_APTCA
-FCIMPL2(FC_BOOL_RET, AssemblyHandle::AptcaCheck, AssemblyBaseObject* pTargetAssemblyUNSAFE, AssemblyBaseObject* pSourceAssemblyUNSAFE)
-{
- FCALL_CONTRACT;
-
- ASSEMBLYREF refTargetAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pTargetAssemblyUNSAFE);
- ASSEMBLYREF refSourceAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pSourceAssemblyUNSAFE);
-
- if ((refTargetAssembly == NULL) || (refSourceAssembly == NULL))
- FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
-
- DomainAssembly *pTargetAssembly = refTargetAssembly->GetDomainAssembly();
- DomainAssembly *pSourceAssembly = refSourceAssembly->GetDomainAssembly();
-
- if (pTargetAssembly == pSourceAssembly)
- FC_RETURN_BOOL(TRUE);
-
- BOOL bResult = TRUE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_2(refSourceAssembly, refTargetAssembly);
- {
- bResult = ( pTargetAssembly->GetAssembly()->AllowUntrustedCaller() || // target assembly allows untrusted callers unconditionally
- pSourceAssembly->GetSecurityDescriptor()->IsFullyTrusted());
- }
- HELPER_METHOD_FRAME_END();
-
- FC_RETURN_BOOL(bResult);
-}
-FCIMPLEND
-#endif // FEATURE_APTCA
void QCALLTYPE ModuleHandle::GetPEKind(QCall::ModuleHandle pModule, DWORD* pdwPEKind, DWORD* pdwMachine)
{
static FCDECL2(FC_BOOL_RET, TypeEQ, Object* left, Object* right);
static FCDECL2(FC_BOOL_RET, TypeNEQ, Object* left, Object* right);
-#ifndef FEATURE_CORECLR
- static FCDECL2(FC_BOOL_RET, IsEquivalentTo, ReflectClassBaseObject *rtType1UNSAFE, ReflectClassBaseObject *rtType2UNSAFE);
- static FCDECL1(FC_BOOL_RET, IsEquivalentType, ReflectClassBaseObject *rtTypeUNSAFE);
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_COMINTEROP
static FCDECL1(FC_BOOL_RET, IsWindowsRuntimeObjectType, ReflectClassBaseObject *rtTypeUNSAFE);
static FCDECL1(ReflectModuleBaseObject*, GetManifestModule, AssemblyBaseObject *pAssemblyUNSAFE);
static FCDECL1(INT32, GetToken, AssemblyBaseObject *pAssemblyUNSAFE);
-#ifdef FEATURE_APTCA
- static FCDECL2(FC_BOOL_RET, AptcaCheck, AssemblyBaseObject *pTargetAssemblyUNSAFE, AssemblyBaseObject *pSourceAssemblyUNSAFE);
-#endif // FEATURE_APTCA
};
class SignatureNative;
delete static_cast<SharedSecurityDescriptor *>(descriptor);
}
-#ifndef FEATURE_CORECLR
-IPEFileSecurityDescriptor* Security::CreatePEFileSecurityDescriptor(AppDomain* pDomain, PEFile *pPEFile)
-{
- WRAPPER_NO_CONTRACT;
-
- return static_cast<IPEFileSecurityDescriptor*>(new PEFileSecurityDescriptor(pDomain, pPEFile));
-}
-#endif
BOOL Security::IsTransparencyEnforcementEnabled()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
// No transparency enforcement in .NET Core
return FALSE;
-#else
-
-#ifdef _DEBUG
- if (g_pConfig->DisableTransparencyEnforcement())
- return FALSE;
-#endif
-
- return TRUE;
-#endif // FEATURE_CORECLR
}
//---------------------------------------------------------------------------------------
#include "securitydeclarative.h"
#include "securitytransparentassembly.h"
-#ifdef FEATURE_APTCA
-#include "aptca.h"
-#endif
class IAssemblySecurityDescriptor;
class IApplicationSecurityDescriptor;
inline void SaveCache();
// Policy
-#ifdef FEATURE_CAS_POLICY
- inline bool IsProcessWideLegacyCasPolicyEnabled();
- inline bool CanLoadFromRemoteSources();
-#endif // FEATURE_CAS_POLICY
BOOL IsTransparencyEnforcementEnabled();
// other CAS Actions
inline void Demand(SecurityStackWalkType eType, OBJECTREF demand) ;
-#ifdef FEATURE_CAS_POLICY
- inline void DemandGrantSet(IAssemblySecurityDescriptor *psdAssembly);
-#endif // FEATURE_CAS_POLICY
inline void DemandSet(SecurityStackWalkType eType, OBJECTREF demand) ;
inline void DemandSet(SecurityStackWalkType eType, PsetCacheEntry *pPCE, DWORD dwAction) ;
-#ifdef FEATURE_CAS_POLICY
- inline void ReflectionTargetDemand(DWORD dwPermission, IAssemblySecurityDescriptor *psdTarget);
- inline void ReflectionTargetDemand(DWORD dwPermission,
- IAssemblySecurityDescriptor *psdTarget,
- DynamicResolver * pAccessContext);
-#endif // FEATURE_CAS_POLICY
inline void SpecialDemand(SecurityStackWalkType eType, DWORD whatPermission) ;
inline void InheritanceLinkDemandCheck(Assembly *pTargetAssembly, MethodDesc * pMDLinkDemand);
IAssemblySecurityDescriptor* CreateAssemblySecurityDescriptor(AppDomain *pDomain, DomainAssembly *pAssembly, LoaderAllocator *pLoaderAllocator);
ISharedSecurityDescriptor* CreateSharedSecurityDescriptor(Assembly* pAssembly);
void DeleteSharedSecurityDescriptor(ISharedSecurityDescriptor *descriptor);
-#ifndef FEATURE_CORECLR
- IPEFileSecurityDescriptor* CreatePEFileSecurityDescriptor(AppDomain* pDomain, PEFile *pPEFile);
-#endif
inline void SetDefaultAppDomainProperty(IApplicationSecurityDescriptor* pASD);
inline void SetDefaultAppDomainEvidenceProperty(IApplicationSecurityDescriptor* pASD);
// security enforcement
inline BOOL ContainsBuiltinCASPermsOnly(CORSEC_ATTRSET* pAttrSet);
-#ifdef FEATURE_APTCA
- inline BOOL IsUntrustedCallerCheckNeeded(MethodDesc *pCalleeMD, Assembly *pCallerAssem = NULL) ;
- inline void DoUntrustedCallerChecks(Assembly *pCaller, MethodDesc *pCalee, BOOL fFullStackWalk) ;
-
- inline bool NativeImageHasValidAptcaDependencies(PEImage *pNativeImage, DomainAssembly *pDomainAssembly);
-
- inline SString GetAptcaKillBitAccessExceptionContext(Assembly *pTargetAssembly);
- inline SString GetConditionalAptcaAccessExceptionContext(Assembly *pTargetAssembly);
-#endif // FEATURE_APTCA
inline bool SecurityCalloutQuickCheck(MethodDesc *pCallerMD);
virtual void Resolve() = 0;
virtual BOOL IsResolved() const = 0;
-#ifdef FEATURE_CAS_POLICY
- virtual OBJECTREF GetEvidence() = 0;
- virtual BOOL IsEvidenceComputed() const = 0;
- virtual void SetEvidence(OBJECTREF evidence) = 0;
-#endif // FEATURE_CAS_POLICY
virtual OBJECTREF GetGrantedPermissionSet(OBJECTREF* RefusedPermissions = NULL) = 0;
#endif // !DACCESS_COMPILE
// or if unmanaged code access is allowed at this time
virtual DWORD GetDomainWideSpecialFlag() const = 0;
-#ifdef FEATURE_CAS_POLICY
- virtual void SetLegacyCasPolicyEnabled() = 0;
- virtual BOOL IsLegacyCasPolicyEnabled() = 0;
- virtual BOOL AllowsLoadsFromRemoteSources() = 0;
-#endif // FEATURE_CAS_POLICY
-#ifdef FEATURE_APTCA
- virtual ConditionalAptcaCache *GetConditionalAptcaCache() = 0;
- virtual void SetCanonicalConditionalAptcaList(LPCWSTR wszCanonicalConditionalAptcaList) = 0;
-#endif // FEATURE_APTCA
#endif // !DACCESS_COMPILE
};
virtual void ResolvePolicy(ISharedSecurityDescriptor *pSharedDesc, BOOL fShouldSkipPolicyResolution) = 0;
-#ifdef FEATURE_CAS_POLICY
- virtual HRESULT LoadSignature( COR_TRUST **ppSignature = NULL) = 0;
-
- virtual void SetAdditionalEvidence(OBJECTREF evidence) = 0;
- virtual BOOL HasAdditionalEvidence() = 0;
- virtual OBJECTREF GetAdditionalEvidence() = 0;
- virtual void SetEvidenceFromPEFile(IPEFileSecurityDescriptor *pPEFileSecDesc) = 0;
-#endif // FEATURE_CAS_POLICY
virtual void PropagatePermissionSet(OBJECTREF GrantedPermissionSet, OBJECTREF DeniedPermissionSet, DWORD dwSpecialFlags) = 0;
-#ifndef FEATURE_CORECLR
- virtual BOOL AllowApplicationSpecifiedAppDomainManager() = 0;
-#endif
// Check to make sure that security will allow this assembly to load. Throw an exception if the
// assembly should be forbidden from loading for security related purposes
virtual Assembly* GetAssembly() = 0;
};
-#ifndef FEATURE_CORECLR
-class IPEFileSecurityDescriptor : public ISecurityDescriptor
-{
-public:
- virtual BOOL AllowBindingRedirects() = 0;
-};
-#endif
#include "security.inl"
#include "securitydeclarative.inl"
WRAPPER_NO_CONTRACT;
SecurityPolicy::Stop();
}
-#ifdef FEATURE_CAS_POLICY
-inline void Security::SaveCache()
-{
- WRAPPER_NO_CONTRACT;
- SecurityPolicy::SaveCache();
-}
-#endif
// ----------------------------------------
// SecurityPolicy
// ----------------------------------------
-#ifdef FEATURE_CAS_POLICY
-
-//---------------------------------------------------------------------------------------
-//
-// Determine if the entire process is running with CAS policy enabled for legacy
-// compatibility. If this value is false, the CLR does not apply any security policy.
-// Instead, it defers to a host if one is present or grants assemblies full trust.
-//
-
-inline bool Security::IsProcessWideLegacyCasPolicyEnabled()
-{
- LIMITED_METHOD_CONTRACT;
-
- // APPX precludes the use of legacy CAS policy
- if (AppX::IsAppXProcess())
- {
- return false;
- }
-
- return CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Security_LegacyCasPolicy) ||
- CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Security_NetFx40LegacySecurityPolicy);
-}
-
-//---------------------------------------------------------------------------------------
-//
-// In pre-v4 versions of the CLR, doing a LoadFrom for a file in a remote location would
-// implicitly sandbox that assembly. If CAS policy is disabled, then these applications
-// will suddenly be granting full trust to assemblies they expected to be sandboxed. In
-// order to prevent this, these LoadFroms are disabled unless the application has explcitly
-// configured itself to allow them.
-//
-// This method returns the a value that indicates if the application has indicated that it
-// is safe to LoadFrom remote locations and that the CLR should not block these loads.
-//
-
-inline bool Security::CanLoadFromRemoteSources()
-{
- WRAPPER_NO_CONTRACT;
- return !!CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Security_LoadFromRemoteSources);
-}
-
-#endif // FEATURE_CAS_POLICY
inline BOOL Security::CanCallUnmanagedCode(Module *pModule)
{
inline void Security::CheckLinkDemandAgainstAppDomain(MethodDesc *pMD)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityDeclarative::CheckLinkDemandAgainstAppDomain(pMD);
-#endif
}
inline void Security::LinktimeCheckMethod(Assembly *pCaller, MethodDesc *pCallee)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityDeclarative::LinktimeCheckMethod(pCaller, pCallee);
-#endif
}
inline void Security::ClassInheritanceCheck(MethodTable *pClass, MethodTable *pParent)
inline void Security::DoDeclarativeActions(MethodDesc *pMD, DeclActionInfo *pActions, LPVOID pSecObj, MethodSecurityDescriptor *pMSD)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityDeclarative::DoDeclarativeActions(pMD, pActions, pSecObj, pMSD);
-#endif
}
#ifndef DACCESS_COMPILE
inline void Security::CheckNonCasDemand(OBJECTREF *prefDemand)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityDeclarative::CheckNonCasDemand(prefDemand);
-#endif
}
#endif // #ifndef DACCESS_COMPILE
inline void Security::Demand(SecurityStackWalkType eType, OBJECTREF demand)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityStackWalk::Demand(eType, demand);
-#endif
}
-#ifdef FEATURE_CAS_POLICY
-inline void Security::DemandGrantSet(IAssemblySecurityDescriptor *psdAssembly)
-{
- WRAPPER_NO_CONTRACT;
- SecurityStackWalk::DemandGrantSet(static_cast<AssemblySecurityDescriptor*>(psdAssembly));
-}
-#endif // FEATURE_CAS_POLICY
inline void Security::DemandSet(SecurityStackWalkType eType, OBJECTREF demand)
{
MODE_COOPERATIVE;
}
CONTRACTL_END;
-#ifdef FEATURE_CAS_POLICY
- SecurityStackWalk::DemandSet(eType, demand);
-#endif
}
inline void Security::DemandSet(SecurityStackWalkType eType, PsetCacheEntry *pPCE, DWORD dwAction)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityStackWalk::DemandSet(eType, pPCE, dwAction);
-#endif
}
-#ifdef FEATURE_CAS_POLICY
-inline void Security::ReflectionTargetDemand(DWORD dwPermission, IAssemblySecurityDescriptor *psdTarget)
-{
- WRAPPER_NO_CONTRACT;
- SecurityStackWalk::ReflectionTargetDemand(dwPermission, static_cast<AssemblySecurityDescriptor*>(psdTarget));
-}
-
-inline void Security::ReflectionTargetDemand(DWORD dwPermission,
- IAssemblySecurityDescriptor *psdTarget,
- DynamicResolver * pAccessContext)
-{
- WRAPPER_NO_CONTRACT;
- SecurityStackWalk::ReflectionTargetDemand(dwPermission, static_cast<AssemblySecurityDescriptor*>(psdTarget), pAccessContext);
-}
-#endif // FEATURE_CAS_POLICY
inline void Security::SpecialDemand(SecurityStackWalkType eType, DWORD whatPermission)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityStackWalk::SpecialDemand(eType, whatPermission);
-#endif
}
inline void Security::InheritanceLinkDemandCheck(Assembly *pTargetAssembly, MethodDesc * pMDLinkDemand)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityDeclarative::InheritanceLinkDemandCheck(pTargetAssembly, pMDLinkDemand);
-#endif
}
inline void Security::FullTrustInheritanceDemand(Assembly *pTargetAssembly)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityDeclarative::FullTrustInheritanceDemand(pTargetAssembly);
-#endif
}
inline void Security::FullTrustLinkDemand(Assembly *pTargetAssembly)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityDeclarative::FullTrustLinkDemand(pTargetAssembly);
-#endif
}
#ifdef FEATURE_COMPRESSEDSTACK
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
// Always skip verification on CoreCLR
return TRUE;
-#else
-
- // Special case the System.Object..ctor:
- // System.Object..ctor is not verifiable according to current verifier rules (that require to call the base
- // class ctor). But since we want System.Object..ctor() to be marked transparent, it cannot be unverifiable
- // (v4 security rules prohibit transparent code from being unverifiable)
-
-#ifndef DACCESS_COMPILE
- if (g_pObjectCtorMD == pMD)
- return TRUE;
-#endif
-
- // In AppX, all dynamic code (dynamic assemblies and dynamic methods) should be verified..
- if (AppX::IsAppXProcess() && !AppX::IsAppXDesignMode())
- {
- if (pMD->IsLCGMethod() || pMD->GetAssembly()->IsDynamic())
- return FALSE;
- }
-
- BOOL fCanSkipVerification = Security::CanSkipVerification(pMD->GetAssembly()->GetDomainAssembly());
- if (fCanSkipVerification)
- {
- // check for transparency
- if (SecurityTransparent::IsMethodTransparent(pMD))
- {
- ModuleSecurityDescriptor *pModuleSecDesc = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pMD->GetAssembly());
- if (!pModuleSecDesc->CanTransparentCodeSkipVerification())
- {
- return FALSE;
- }
- }
- }
- return fCanSkipVerification;
-#endif // !FEATURE_CORECLR
}
#endif //!DACCESS_COMPILE
return SecurityAttributes::ContainsBuiltinCASPermsOnly(pAttrSet);
}
-#ifdef FEATURE_APTCA
-inline BOOL Security::IsUntrustedCallerCheckNeeded(MethodDesc *pCalleeMD, Assembly *pCallerAssem)
-{
- WRAPPER_NO_CONTRACT;
- return SecurityDeclarative::IsUntrustedCallerCheckNeeded(pCalleeMD, pCallerAssem);
-}
-
-inline void Security::DoUntrustedCallerChecks(Assembly *pCaller, MethodDesc *pCalee, BOOL fFullStackWalk)
-{
- WRAPPER_NO_CONTRACT;
- SecurityDeclarative::DoUntrustedCallerChecks(pCaller, pCalee, fFullStackWalk);
-}
-
-inline bool Security::NativeImageHasValidAptcaDependencies(PEImage *pNativeImage, DomainAssembly *pDomainAssembly)
-{
- WRAPPER_NO_CONTRACT;
- return ::NativeImageHasValidAptcaDependencies(pNativeImage, pDomainAssembly);
-}
-
-inline SString Security::GetAptcaKillBitAccessExceptionContext(Assembly *pTargetAssembly)
-{
- WRAPPER_NO_CONTRACT;
- return ::GetAptcaKillBitAccessExceptionContext(pTargetAssembly);
-}
-
-inline SString Security::GetConditionalAptcaAccessExceptionContext(Assembly *pTargetAssembly)
-{
- WRAPPER_NO_CONTRACT;
- return ::GetConditionalAptcaAccessExceptionContext(pTargetAssembly);
-}
-
-#endif // FEATURE_APTCA
inline bool Security::SecurityCalloutQuickCheck(MethodDesc *pCallerMD)
{
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_APTCA
- if (!DomainCanShareAptcaAssembly(pAssembly))
- {
- return false;
- }
-#endif // FEATURE_APTCA
return true;
}
}
CONTRACTL_END;
-#ifndef FEATURE_CAS_POLICY
return TRUE;
-#else
- // either the desired flag (often 0) or fully trusted will do
- flags |= (1<<SECURITY_FULL_TRUST);
-
- // in order for us to use the threadwide state it has to be the case that there have been no
- // overrides since the evaluation (e.g. no denies) We keep the state up-to-date by updating
- // it whenever a new AppDomainStackEntry is pushed on the AppDomainStack attached to the thread.
- // When we evaluate the demand, we always intersect the current thread state with the AppDomain
- // wide flags, which are updated anytime a new Assembly is loaded into that domain.
- //
- // note if the flag is clear we still might be able to satisfy the demand if we do the full
- // stackwalk.
- //
- // this code is very perf sensitive, do not make changes here without running
- // a lot of interop and declarative security benchmarks
- //
- // it's important that we be able to do these checks without having to touch objects
- // other than the thread itself -- that's where a big part of the speed comes from
- // L1 cache misses are at a premium on this code path -- never mind L2...
- // main memory is right out :)
-
- Thread* pThread = GetThread();
- return ((pThread->GetOverridesCount() == 0) &&
- pThread->CheckThreadWideSpecialFlag(flags) &&
- static_cast<ApplicationSecurityDescriptor*>(pThread->GetDomain()->GetSecurityDescriptor())->CheckDomainWideSpecialFlag(flags));
-#endif
}
// Returns true if everyone is fully trusted or has the indicated flags AND we're not in legacy CAS mode
// Creates a new permission set
OBJECTREF CreatePermissionSet(BOOL fTrusted);
-#ifdef FEATURE_CAS_POLICY
- // Takes two PermissionSets (referenced by index) and merges them (unions or intersects
- // depending on fIntersect) and returns the index of the merged PermissionSet
- PsetCacheEntry* MergePermissionSets(IN PsetCacheEntry *pPCE1, IN PsetCacheEntry *pPCE2, IN bool fIntersect, IN DWORD dwAction);
-#endif // FEATURE_CAS_POLICY
// Uses new to create the byte array that is returned.
void CopyByteArrayToEncoding(IN U1ARRAYREF* pArray,
OUT PBYTE* pbData,
OUT DWORD* cbData);
-#ifdef FEATURE_CAS_POLICY
- void EncodePermissionSet(IN OBJECTREF* pRef,
- OUT PBYTE* ppbData,
- OUT DWORD* pcbData);
-#endif // FEATURE_CAS_POLICY
// Generic routine, use with encoding calls that
// use the EncodePermission client data
void AttrArrayToPermissionSet(OBJECTREF* attrArray, bool fSerialize, DWORD attrCount, BYTE **ppbOutput, DWORD *pcbOutput, BYTE **ppbNonCasOutput, DWORD *pcbNonCasOutput, bool fAllowEmptyPermissionSet, OBJECTREF* pPermSet);
void AttrSetBlobToPermissionSets(IN BYTE* pbRawPermissions, IN DWORD cbRawPermissions, OUT OBJECTREF* pObj, IN DWORD dwAction);
-#ifdef FEATURE_CAS_POLICY
- void XmlToPermissionSet(PBYTE pbXmlBlob,
- DWORD cbXmlBlob,
- OBJECTREF* pPermSet,
- OBJECTREF* pEncoding,
- PBYTE pbNonCasXmlBlob,
- DWORD cbNonCasXmlBlob,
- OBJECTREF* pNonCasPermSet,
- OBJECTREF* pNonCasEncoding);
-#endif // FEATURE_CAS_POLICY
bool ActionAllowsNullPermissionSet(CorDeclSecurity action);
+++ /dev/null
-// 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.
-//
-// File: SecurityConfig.cpp
-//
-
-//
-// Native implementation for security config access and manipulation
-//
-
-
-// #SecurityConfigFormat
-//
-// The security config system resides outside of the rest
-// of the config system since our needs are different. The
-// unmanaged portion of the security config system is only
-// concerned with data file/cache file pairs, not what they
-// are used for. It performs all the duties of reading data
-// from the disk, saving data back to the disk, and maintaining
-// the policy and quick cache data structures.
-//
-// FILE FORMAT
-//
-// The data file is a purely opaque blob for the unmanaged
-// code; however, the cache file is constructed and maintained
-// completely in the unmanaged code. It's format is as follows:
-//
-// CacheHeader
-// |
-// +-- dummyFileTime (FILETIME, 8 bytes) = this exists to make sure we don't read old format cache files. Must be set to {1, 0}.
-// |
-// +-- version (DWORD) = The version of this config file.
-// |
-// +-- configFileTime (FILETIME, 8 bytes) = The file time of the config file associated with this cache file.
-// |
-// +-- isSecurityOn (DWORD, 4 bytes) = This is currently not used.
-// |
-// +-- quickCache (DWORD, 4 bytes) = Used as a bitfield to maintain the information for the QuickCache. See the QuickCache section for more details.
-// |
-// +-- registryExtensionsInfo (struct RegistryExtensionsInfo) = Indicates whether this cache file was generated in the presence of registry extensions.
-// |
-// +-- numEntries (DWORD, 4 bytes) = The number of policy cache entries in the latter portion of this cache file.
-// |
-// +-- sizeConfig (DWORD, 4 bytes) = The size of the config information stored in the latter portion of this cache file.
-//
-// Config Data (if any)
-// The cache file can include an entire copy of this
-// information in the adjoining config file. This is
-// necessary since the cache often allows us to make
-// policy decisions without having parsed the data in
-// the config file. In order to guarantee that the config
-// data used by this process is not altered in the
-// meantime, we need to store the data in a readonly
-// location. Due to the design of the caching system
-// the cache file is locked when it is opened and therefore
-// is the perfect place to store this information. The
-// other alternative is to hold it in memory, but since
-// this can amount to many kilobytes of data we decided
-// on this design.
-//
-// List of CacheEntries
-// |
-// +-- CacheEntry
-// | |
-// | +-- numItemsInKey (DWORD, 4 bytes) = The number of evidence objects serialized in the key blob
-// | |
-// | +-- keySize (DWORD, 4 bytes) = The number of bytes in the key blob.
-// | |
-// | +-- dataSize (DWORD, 4 bytes) = The number of bytes in the data blob.
-// | |
-// | +-- keyBlob (raw) = A raw blob representing the serialized evidence.
-// | |
-// | +-- dataBlob (raw) = A raw blob representing an XML serialized PolicyStatement
-// |
-// +-- ...
-
-#include "common.h"
-
-#ifdef FEATURE_CAS_POLICY
-
-#include "securityconfig.h"
-
-// Header version of the cache file.
-#define CONFIG_VERSION 2
-// This controls the maximum size of the cache file.
-#define MAX_CACHEFILE_SIZE (1 << 20)
-
-#define SIZE_OF_ENTRY( X ) sizeof( CacheEntryHeader ) + X->header.keySize + X->header.dataSize
-#define MAX_NUM_LENGTH 16
-
-WCHAR* SecurityConfig::wcscatDWORD( __out_ecount(cchdst) __out_z WCHAR* dst, size_t cchdst, DWORD num )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END
-
- _ASSERTE( SecurityConfig::dataLock_.OwnedByCurrentThread() );
-
- static WCHAR buffer[MAX_NUM_LENGTH];
-
- buffer[MAX_NUM_LENGTH-1] = W('\0');
-
- size_t index = MAX_NUM_LENGTH-2;
-
- if (num == 0)
- {
- buffer[index--] = W('0');
- }
- else
- {
- while (num != 0)
- {
- buffer[index--] = (WCHAR)(W('0') + (num % 10));
- num = num / 10;
- }
- }
-
- wcscat_s( dst, cchdst, buffer + index + 1 );
-
- return dst;
-}
-
-inline WCHAR * Wszdup(const WCHAR * str)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- size_t len = wcslen(str) + 1;
- WCHAR * ret = new WCHAR[len];
- wcscpy_s(ret, len, str);
- return ret;
-}
-
-struct CacheHeader
-{
- FILETIME dummyFileTime;
- DWORD version;
- FILETIME configFileTime;
- DWORD isSecurityOn, quickCache;
- SecurityConfig::RegistryExtensionsInfo registryExtensionsInfo;
- DWORD numEntries, sizeConfig;
-
- CacheHeader() : isSecurityOn( (DWORD) -1 ), quickCache( 0 ), numEntries( 0 ), sizeConfig( 0 )
- {
- WRAPPER_NO_CONTRACT;
- memset( &this->configFileTime, 0, sizeof( configFileTime ) );
- dummyFileTime.dwLowDateTime = 1;
- dummyFileTime.dwHighDateTime = 0;
- version = CONFIG_VERSION;
- memset(®istryExtensionsInfo, 0, sizeof(registryExtensionsInfo));
- _ASSERTE( IsValid() && "CacheHeader constructor should make it valid" );
- };
-
- bool IsValid()
- {
- LIMITED_METHOD_CONTRACT;
- return dummyFileTime.dwLowDateTime == 1 &&
- dummyFileTime.dwHighDateTime == 0 &&
- version == CONFIG_VERSION;
- }
-};
-
-struct CacheEntryHeader
-{
- DWORD numItemsInKey;
- DWORD keySize;
- DWORD dataSize;
-};
-
-struct CacheEntry
-{
- CacheEntryHeader header;
- BYTE* key;
- BYTE* data;
- DWORD cachePosition;
- BOOL used;
-
- CacheEntry() : key( NULL ), data( NULL ), used( FALSE )
- {
- LIMITED_METHOD_CONTRACT;
- };
-
- ~CacheEntry( void )
- {
- WRAPPER_NO_CONTRACT;
- delete [] key;
- delete [] data;
- }
-};
-
-struct Data
-{
- enum State
- {
- None = 0x0,
- UsingCacheFile = 0x1,
- CopyCacheFile = 0x2,
- CacheUpdated = 0x4,
- UsingConfigFile = 0x10,
- CacheExhausted = 0x20,
- NewConfigFile = 0x40
- };
-
- INT32 id;
- WCHAR* configFileName;
- WCHAR* cacheFileName;
- WCHAR* cacheFileNameTemp;
-
- LPBYTE configData;
- DWORD configDataSize;
- FILETIME configFileTime;
- FILETIME cacheFileTime;
- CacheHeader header;
- ArrayList* oldCacheEntries;
- ArrayList* newCacheEntries;
- State state;
- DWORD cacheCurrentPosition;
- HANDLE cache;
- PBYTE configBuffer;
- DWORD sizeConfig;
- SecurityConfig::ConfigRetval initRetval;
- DWORD newEntriesSize;
-
- Data( INT32 id )
- : id( id ),
- configFileName( NULL ),
- cacheFileName( NULL ),
- configData( NULL ),
- oldCacheEntries( new ArrayList ),
- newCacheEntries( new ArrayList ),
- state( Data::None ),
- cache( INVALID_HANDLE_VALUE ),
- configBuffer( NULL ),
- newEntriesSize( 0 )
- {
- LIMITED_METHOD_CONTRACT;
- }
-
- Data( INT32 id, STRINGREF* configFile )
- : id( id ),
- cacheFileName( NULL ),
- configData( NULL ),
- oldCacheEntries( new ArrayList ),
- newCacheEntries( new ArrayList ),
- state( Data::None ),
- cache( INVALID_HANDLE_VALUE ),
- configBuffer( NULL ),
- newEntriesSize( 0 )
- {
- CONTRACTL {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(*configFile != NULL);
- } CONTRACTL_END;
-
- configFileName = Wszdup( (*configFile)->GetBuffer() );
- cacheFileName = NULL;
- cacheFileNameTemp = NULL;
- }
-
- Data( INT32 id, STRINGREF* configFile, STRINGREF* cacheFile )
- : id( id ),
- configData( NULL ),
- oldCacheEntries( new ArrayList ),
- newCacheEntries( new ArrayList ),
- state( Data::None ),
- cache( INVALID_HANDLE_VALUE ),
- configBuffer( NULL ),
- newEntriesSize( 0 )
- {
- CONTRACTL {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(*configFile != NULL);
- } CONTRACTL_END;
-
- configFileName = Wszdup( (*configFile)->GetBuffer() );
-
- if (cacheFile != NULL)
- {
- // Since temp cache files can stick around even after the process that
- // created them, we want to make sure they are fairly unique (if they
- // aren't, we'll just fail to save cache information, which is not good
- // but it won't cause anyone to crash or anything). The unique name
- // algorithm used here is to append the process id and tick count to
- // the name of the cache file.
-
- cacheFileName = Wszdup( (*cacheFile)->GetBuffer() );
- size_t len = wcslen( cacheFileName ) + 1 + 2 * MAX_NUM_LENGTH;
- cacheFileNameTemp = new WCHAR[len];
- wcscpy_s( cacheFileNameTemp, len, cacheFileName );
- wcscat_s( cacheFileNameTemp, len, W(".") );
- SecurityConfig::wcscatDWORD( cacheFileNameTemp, len, GetCurrentProcessId() );
- wcscat_s( cacheFileNameTemp, len, W(".") );
- SecurityConfig::wcscatDWORD( cacheFileNameTemp, len, GetTickCount() );
- }
- else
- {
- cacheFileName = NULL;
- cacheFileNameTemp = NULL;
- }
- }
-
- Data( INT32 id, const WCHAR* configFile, const WCHAR* cacheFile )
- : id( id ),
- configData( NULL ),
- oldCacheEntries( new ArrayList ),
- newCacheEntries( new ArrayList ),
- state( Data::None ),
- cache( INVALID_HANDLE_VALUE ),
- configBuffer( NULL ),
- newEntriesSize( 0 )
-
- {
- CONTRACTL {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(*configFile != NULL);
- } CONTRACTL_END;
-
- configFileName = Wszdup( configFile );
-
- if (cacheFile != NULL)
- {
- cacheFileName = Wszdup( cacheFile );
- size_t len = wcslen( cacheFileName ) + 1 + 2 * MAX_NUM_LENGTH;
- cacheFileNameTemp = new WCHAR[len];
- wcscpy_s( cacheFileNameTemp, len, cacheFileName );
- wcscat_s( cacheFileNameTemp, len, W(".") );
- SecurityConfig::wcscatDWORD( cacheFileNameTemp, len, GetCurrentProcessId() );
- wcscat_s( cacheFileNameTemp, len, W(".") );
- SecurityConfig::wcscatDWORD( cacheFileNameTemp, len, GetTickCount() );
- }
- else
- {
- cacheFileName = NULL;
- cacheFileNameTemp = NULL;
- }
- }
-
- void Reset( void )
- {
- CONTRACTL {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- delete [] configBuffer;
- configBuffer = NULL;
-
- if (cache != INVALID_HANDLE_VALUE)
- {
- CloseHandle( cache );
- cache = INVALID_HANDLE_VALUE;
- }
-
- if (cacheFileNameTemp != NULL)
- {
- // Note: we don't check a return value here as the worst thing that
- // happens is we leave a spurious cache file.
-
- WszDeleteFile( cacheFileNameTemp );
- }
-
- if (configData != NULL)
- delete [] configData;
- configData = NULL;
-
- DeleteAllEntries();
- header = CacheHeader();
-
- oldCacheEntries = new ArrayList();
- newCacheEntries = new ArrayList();
-
- }
-
- void Cleanup( void )
- {
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- if (cache != INVALID_HANDLE_VALUE)
- {
- CloseHandle( cache );
- cache = INVALID_HANDLE_VALUE;
- }
-
- if (cacheFileNameTemp != NULL)
- {
- // Note: we don't check a return value here as the worst thing that
- // happens is we leave a spurious cache file.
-
- WszDeleteFile( cacheFileNameTemp );
- }
- }
-
- ~Data( void )
- {
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- Cleanup();
- delete [] configBuffer;
-
- delete [] configFileName;
- delete [] cacheFileName;
- delete [] cacheFileNameTemp;
-
- if (configData != NULL)
- delete [] configData;
- DeleteAllEntries();
- }
-
- void DeleteAllEntries( void );
-};
-
-void Data::DeleteAllEntries( void )
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- ArrayList::Iterator iter;
-
- if (oldCacheEntries != NULL)
- {
- iter = oldCacheEntries->Iterate();
-
- while (iter.Next())
- {
- delete (CacheEntry*) iter.GetElement();
- }
-
- delete oldCacheEntries;
- oldCacheEntries = NULL;
- }
-
- if (newCacheEntries != NULL)
- {
- iter = newCacheEntries->Iterate();
-
- while (iter.Next())
- {
- delete (CacheEntry*) iter.GetElement();
- }
-
- delete newCacheEntries;
- newCacheEntries = NULL;
- }
-}
-
-void* SecurityConfig::GetData( INT32 id )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END
-
- ArrayList::Iterator iter = entries_.Iterate();
-
- while (iter.Next())
- {
- Data* data = (Data*)iter.GetElement();
-
- if (data->id == id)
- {
- return data;
- }
- }
-
- return NULL;
-}
-
-static BOOL CacheOutOfDate( FILETIME* configFileTime, __in_z WCHAR* configFileName, __in_z_opt WCHAR* cacheFileName )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_PREEMPTIVE;
- }
- CONTRACTL_END
-
- BOOL retval = TRUE;
- BOOL deleteFile = FALSE;
-
- HandleHolder config(WszCreateFile( configFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ));
-
- if (config.GetValue() == INVALID_HANDLE_VALUE)
- {
- goto CLEANUP;
- }
-
- // Get the last write time for both files.
-
- FILETIME newConfigTime;
-
- if (!GetFileTime( config.GetValue(), NULL, NULL, &newConfigTime ))
- {
- goto CLEANUP;
- }
-
- if (CompareFileTime( configFileTime, &newConfigTime ) != 0)
- {
- // Cache is dated. Delete the cache.
- deleteFile = TRUE;
- goto CLEANUP;
- }
-
- retval = FALSE;
-
-CLEANUP:
- // Note: deleting this file is a perf optimization so that
- // we don't have to do this file time comparison next time.
- // Therefore, if it fails for some reason we just loss a
- // little perf.
-
- if (deleteFile && cacheFileName != NULL)
- WszDeleteFile( cacheFileName );
-
- return retval;
-}
-
-static BOOL CacheOutOfDate( FILETIME* cacheFileTime, HANDLE cache, __in_z_opt WCHAR* cacheFileName )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_PREEMPTIVE;
- }
- CONTRACTL_END
-
- BOOL retval = TRUE;
-
- // Get the last write time for both files.
-
- FILETIME newCacheTime;
-
- if (!GetFileTime( cache, NULL, NULL, &newCacheTime ))
- {
- goto CLEANUP;
- }
-
- if (CompareFileTime( cacheFileTime, &newCacheTime ) != 0)
- {
- // Cache is dated. Delete the cache.
- // Note: deleting this file is a perf optimization so that
- // we don't have to do this file time comparison next time.
- // Therefore, if it fails for some reason we just loss a
- // little perf.
-
- if (cacheFileName != NULL)
- {
- CloseHandle( cache );
- WszDeleteFile( cacheFileName );
- }
- goto CLEANUP;
- }
-
- retval = FALSE;
-
-CLEANUP:
- return retval;
-}
-
-static BOOL CacheOutOfDate( FILETIME* configTime, FILETIME* cachedConfigTime )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_PREEMPTIVE;
- }
- CONTRACTL_END
-
- DWORD result = CompareFileTime( configTime, cachedConfigTime );
-
- return result != 0;
-}
-
-static DWORD GetShareFlags()
-{
- LIMITED_METHOD_CONTRACT;
-
- return FILE_SHARE_READ | FILE_SHARE_DELETE;
-}
-
-static DWORD WriteFileData( HANDLE file, LPCBYTE data, DWORD size )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END
-
- DWORD totalBytesWritten = 0;
- DWORD bytesWritten;
-
- do
- {
- if (WriteFile( file, data, size - totalBytesWritten, &bytesWritten, NULL ) == 0)
- {
- return E_FAIL;
- }
- if (bytesWritten == 0)
- {
- return E_FAIL;
- }
- totalBytesWritten += bytesWritten;
- } while (totalBytesWritten < size);
-
- return S_OK;
-}
-
-// the data argument to this function can be a pointer to GC heap.
-// We do ensure cooperative mode before we call this function using a pointer to GC heap,
-// so we can't change GC mode inside this function.
-// Greg will look into the ways to pin the object.
-
-static DWORD ReadFileData( HANDLE file, PBYTE data, DWORD size )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END
-
- DWORD totalBytesRead = 0;
- DWORD bytesRead;
- do
- {
- if (ReadFile( file, data, size - totalBytesRead, &bytesRead, NULL ) == 0)
- {
- return E_FAIL;
- }
-
- if (bytesRead == 0)
- {
- return E_FAIL;
- }
-
- totalBytesRead += bytesRead;
-
- } while (totalBytesRead < size);
-
- return S_OK;
-}
-
-SecurityConfig::ConfigRetval SecurityConfig::InitData( INT32 id, const WCHAR* configFileName, const WCHAR* cacheFileName )
-{
- STANDARD_VM_CONTRACT;
-
- Data* data = (Data*)GetData( id );
- if (data != NULL)
- {
- return data->initRetval;
- }
-
- if (configFileName == NULL || wcslen( configFileName ) == 0)
- {
- return NoFile;
- }
-
- {
- CrstHolder ch( &dataLock_ );
- data = new (nothrow) Data( id, configFileName, cacheFileName );
- }
-
- if (data == NULL)
- {
- return NoFile;
- }
-
- return InitData( data, TRUE );
-}
-
-
-SecurityConfig::ConfigRetval SecurityConfig::InitData( void* configDataParam, BOOL addToList )
-{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE( configDataParam != NULL );
-
- Data* data = (Data*) configDataParam;
- DWORD cacheSize;
- DWORD configSize;
- ConfigRetval retval = NoFile;
- DWORD shareFlags;
-
- shareFlags = GetShareFlags();
-
- // Crack open the config file.
-
- HandleHolder config(WszCreateFile( data->configFileName, GENERIC_READ, shareFlags, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ));
- if (config == INVALID_HANDLE_VALUE || !GetFileTime( config, NULL, NULL, &data->configFileTime ))
- {
- memset( &data->configFileTime, 0, sizeof( data->configFileTime ) );
- }
- else
- {
- data->state = (Data::State)(Data::UsingConfigFile | data->state);
- }
-
- // If we want a cache file, try to open that up.
- // Note: we do not use a holder for data->cache because the new holder for data will
- // delete the entire data structure which includes closing this handle as necessary.
-
- if (data->cacheFileName != NULL)
- data->cache = WszCreateFile( data->cacheFileName, GENERIC_READ, shareFlags, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
-
- if (data->cache == INVALID_HANDLE_VALUE)
- {
- goto READ_DATA;
- }
-
- // Validate that the cache file is in a good form by checking
- // that it is at least big enough to contain a header.
-
- cacheSize = SafeGetFileSize( data->cache, NULL );
-
- if (cacheSize == 0xFFFFFFFF)
- {
- goto READ_DATA;
- }
-
- if (cacheSize < sizeof( CacheHeader ))
- {
- goto READ_DATA;
- }
-
- // Finally read the data from the file into the buffer.
-
- if (ReadFileData( data->cache, (BYTE*)&data->header, sizeof( CacheHeader ) ) != S_OK)
- {
- goto READ_DATA;
- }
-
- if (!data->header.IsValid())
- {
- goto READ_DATA;
- }
-
- // Check to make sure the cache file and the config file
- // match up by comparing the actual file time of the config
- // file and the config file time stored in the cache file.
-
- if (CacheOutOfDate( &data->configFileTime, &data->header.configFileTime ))
- {
- goto READ_DATA;
- }
-
- if (!GetFileTime( data->cache, NULL, NULL, &data->cacheFileTime ))
- {
- goto READ_DATA;
- }
-
- // Set the file pointer to after both the header and config data (if any) so
- // that we are ready to read cache entries.
-
- if (SetFilePointer( data->cache, sizeof( CacheHeader ) + data->header.sizeConfig, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- {
- goto READ_DATA;
- }
-
- data->cacheCurrentPosition = sizeof( CacheHeader ) + data->header.sizeConfig;
- data->state = (Data::State)(Data::UsingCacheFile | Data::CopyCacheFile | data->state);
-
- retval = (ConfigRetval)(retval | CacheFile);
-
-READ_DATA:
- // If we are not using the cache file but we successfully opened it, we need
- // to close it now. In addition, we need to reset the cache information
- // stored in the Data object to make sure there is no spill over.
-
- if (data->cache != INVALID_HANDLE_VALUE && (data->state & Data::UsingCacheFile) == 0)
- {
- CloseHandle( data->cache );
- data->header = CacheHeader();
- data->cache = INVALID_HANDLE_VALUE;
- }
-
- if (config != INVALID_HANDLE_VALUE)
- {
- configSize = SafeGetFileSize( config, NULL );
-
- if (configSize == 0xFFFFFFFF)
- {
- goto ADD_DATA;
- }
-
- // Be paranoid and only use the cache file version if we find that it has the correct sized
- // blob in it.
-
- if ((data->state & Data::UsingCacheFile) != 0 && configSize == data->header.sizeConfig)
- {
- goto ADD_DATA;
- }
- else
- {
- if (data->cache != INVALID_HANDLE_VALUE)
- {
- CloseHandle( data->cache );
- data->header = CacheHeader();
- data->cache = INVALID_HANDLE_VALUE;
- data->state = (Data::State)(data->state & ~(Data::UsingCacheFile));
- }
-
- data->configData = new BYTE[configSize];
- if (ReadFileData( config, data->configData, configSize ) != S_OK)
- {
- goto ADD_DATA;
- }
- data->configDataSize = configSize;
- }
- retval = (ConfigRetval)(retval | ConfigFile);
- }
-
-ADD_DATA:
- {
- CrstHolder ch(&dataLock_);
-
- if (addToList)
- {
- IfFailThrow(entries_.Append(data));
- }
- }
-
- _ASSERTE( data );
- data->initRetval = retval;
-
- return retval;
-
-};
-
-static CacheEntry* LoadNextEntry( HANDLE cache, Data* data )
-{
- STANDARD_VM_CONTRACT;
-
- if ((data->state & Data::CacheExhausted) != 0)
- return NULL;
-
- NewHolder<CacheEntry> entry(new CacheEntry());
-
- if (SetFilePointer( cache, data->cacheCurrentPosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- {
- return NULL;
- }
-
- if (ReadFileData( cache, (BYTE*)&entry.GetValue()->header, sizeof( CacheEntryHeader ) ) != S_OK)
- {
- return NULL;
- }
-
- entry.GetValue()->cachePosition = data->cacheCurrentPosition + sizeof( entry.GetValue()->header );
-
- data->cacheCurrentPosition += sizeof( entry.GetValue()->header ) + entry.GetValue()->header.keySize + entry.GetValue()->header.dataSize;
-
- if (SetFilePointer( cache, entry.GetValue()->header.keySize + entry->header.dataSize, NULL, FILE_CURRENT ) == INVALID_SET_FILE_POINTER)
- {
- return NULL;
- }
-
- // We append a partially populated entry. CompareEntry is robust enough to handle this.
- IfFailThrow(data->oldCacheEntries->Append( entry ));
-
- return entry.Extract();
-}
-
-static BOOL WriteEntry( HANDLE cache, CacheEntry* entry, HANDLE oldCache = NULL )
-{
- STANDARD_VM_CONTRACT;
-
- if (WriteFileData( cache, (BYTE*)&entry->header, sizeof( CacheEntryHeader ) ) != S_OK)
- {
- return FALSE;
- }
-
- if (entry->key == NULL)
- {
- _ASSERTE (oldCache != NULL);
-
- // We were lazy in reading the entry. Read the key now.
- entry->key = new BYTE[entry->header.keySize];
-
- _ASSERTE (cache != INVALID_HANDLE_VALUE);
-
- if (SetFilePointer( oldCache, entry->cachePosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- return NULL;
-
- if (ReadFileData( oldCache, entry->key, entry->header.keySize ) != S_OK)
- {
- return NULL;
- }
-
- entry->cachePosition += entry->header.keySize;
- }
-
- _ASSERTE( entry->key != NULL );
-
- if (entry->data == NULL)
- {
- _ASSERTE (oldCache != NULL);
-
- // We were lazy in reading the entry. Read the data also.
- entry->data = new BYTE[entry->header.dataSize];
-
- if (SetFilePointer( oldCache, entry->cachePosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- return NULL;
-
- if (ReadFileData( oldCache, entry->data, entry->header.dataSize ) != S_OK)
- return NULL;
-
- entry->cachePosition += entry->header.dataSize;
- }
-
- _ASSERT( entry->data != NULL );
-
- if (WriteFileData( cache, entry->key, entry->header.keySize ) != S_OK)
- {
- return FALSE;
- }
-
- if (WriteFileData( cache, entry->data, entry->header.dataSize ) != S_OK)
- {
- return FALSE;
- }
-
- return TRUE;
-}
-
-BOOL SecurityConfig::SaveCacheData( INT32 id )
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END
-
- GCX_PREEMP();
-
- // Note: this function should only be called at EEShutdown time.
- // This is because we need to close the current cache file in
- // order to delete it. If it ever became necessary to do
- // cache saves while a process we still executing managed code
- // it should be possible to create a locking scheme for usage
- // of the cache handle with very little reordering of the below
- // (as it should always be possible for us to have a live copy of
- // the file and yet still be making the swap).
-
- HandleHolder cache;
- HandleHolder config;
- CacheHeader header;
- BOOL retval = FALSE;
- BOOL fWriteSucceeded = FALSE;
- DWORD numEntriesWritten = 0;
- DWORD amountWritten = 0;
- DWORD sizeConfig = 0;
- NewHolder<BYTE> configBuffer;
- BOOL useConfigData = FALSE;
-
- Data* data = (Data*)GetData( id );
-
- // If there is not data by the id or there is no
- // cache file name associated with the data, then fail.
-
- if (data == NULL || data->cacheFileName == NULL)
- return FALSE;
-
- // If we haven't added anything new to the cache
- // then just return success.
-
- if ((data->state & Data::CacheUpdated) == 0)
- return TRUE;
-
- // If the config file has changed since the process started
- // then our cache data is no longer valid. We'll just
- // return success in this case.
-
- if ((data->state & Data::UsingConfigFile) != 0 && CacheOutOfDate( &data->configFileTime, data->configFileName, NULL ))
- return TRUE;
-
- DWORD fileNameLength = (DWORD)wcslen( data->cacheFileName );
-
- NewArrayHolder<WCHAR> newFileName(new WCHAR[fileNameLength + 5]);
-
- swprintf_s( newFileName.GetValue(), fileNameLength + 5, W("%s%s"), data->cacheFileName, W(".new") );
-
- cache.Assign( WszCreateFile( newFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ) );
-
- for (DWORD RetryCount = 0; RetryCount < 5; RetryCount++)
- {
- if (cache != INVALID_HANDLE_VALUE)
- {
- break;
- }
- else
- {
- DWORD error = GetLastError();
-
- if (error == ERROR_PATH_NOT_FOUND)
- {
- // The directory does not exist, iterate through and try to create it.
-
- WCHAR* currentChar = newFileName;
-
- // Skip the first backslash
-
- while (*currentChar != W('\0'))
- {
- if (*currentChar == W('\\') || *currentChar == W('/'))
- {
- currentChar++;
- break;
- }
- currentChar++;
- }
-
- // Iterate through trying to create each subdirectory.
-
- while (*currentChar != W('\0'))
- {
- if (*currentChar == W('\\') || *currentChar == W('/'))
- {
- *currentChar = W('\0');
-
- if (!WszCreateDirectory( newFileName, NULL ))
- {
- error = GetLastError();
-
- if (error != ERROR_ACCESS_DENIED && error != ERROR_INVALID_NAME && error != ERROR_ALREADY_EXISTS)
- {
- goto CLEANUP;
- }
- }
-
- *currentChar = W('\\');
- }
- currentChar++;
- }
-
- // Try the file creation again
- continue;
- }
- }
-
- // CreateFile failed. Sleep a little and retry, in case a
- // virus scanner caused the creation to fail.
- ClrSleepEx(10, FALSE);
- }
-
- if (cache.GetValue() == INVALID_HANDLE_VALUE)
- goto CLEANUP;
-
- // This code seems complicated only because of the
- // number of cases that we are trying to handle. All we
- // are trying to do is determine the amount of space to
- // leave for the config information.
-
- // If we saved out a new config file during this run, use
- // the config size stored in the Data object itself.
-
- if (data->configData != NULL)
- {
- useConfigData = TRUE;
- }
-
- if ((data->state & Data::NewConfigFile) != 0)
- {
- sizeConfig = data->sizeConfig;
- }
-
- // If we have a cache file, then use the size stored in the
- // cache header.
-
- else if ((data->state & Data::UsingCacheFile) != 0)
- {
- sizeConfig = data->header.sizeConfig;
- }
-
- // If we read in the config data, use the size of the
- // managed byte array that it is stored in.
-
- else if (useConfigData)
- {
- sizeConfig = data->configDataSize;
- }
-
- // Otherwise, check the config file itself to get the size.
-
- else
- {
- DWORD shareFlags;
-
- shareFlags = GetShareFlags();
-
- config.Assign( WszCreateFile( data->configFileName, GENERIC_READ, shareFlags, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ) );
-
- if (config == INVALID_HANDLE_VALUE)
- {
- sizeConfig = 0;
- }
- else
- {
- sizeConfig = SafeGetFileSize( config, NULL );
-
- if (sizeConfig == 0xFFFFFFFF)
- {
- sizeConfig = 0;
- }
- }
- }
-
- // First write the entries.
-
- if (SetFilePointer( cache, sizeof( CacheHeader ) + sizeConfig, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- {
- goto CLEANUP;
- }
-
- // We're going to write out the cache entries in a modified
- // least recently used order, throwing out any that end up
- // taking us past our hardcoded max file size.
-
- {
- // First, write the entries from the cache file that were used.
- // We do this because presumably these are system assemblies
- // and other assemblies used by a number of applications.
-
- ArrayList::Iterator iter;
-
- if ((data->state & Data::UsingCacheFile) != 0)
- {
- iter = data->oldCacheEntries->Iterate();
-
- while (iter.Next() && amountWritten < MAX_CACHEFILE_SIZE)
- {
- CacheEntry* currentEntry = (CacheEntry*)iter.GetElement();
-
- if (currentEntry->used)
- {
- if(!WriteEntry( cache, currentEntry, data->cache ))
- {
- goto CLEANUP;
- }
-
- amountWritten += SIZE_OF_ENTRY( currentEntry );
- numEntriesWritten++;
- }
- }
- }
-
- // Second, write any new cache entries to the file. These are
- // more likely to be assemblies specific to this app.
-
- iter = data->newCacheEntries->Iterate();
-
- while (iter.Next() && amountWritten < MAX_CACHEFILE_SIZE)
- {
- CacheEntry* currentEntry = (CacheEntry*)iter.GetElement();
-
- if (!WriteEntry( cache, currentEntry ))
- {
- goto CLEANUP;
- }
-
- amountWritten += SIZE_OF_ENTRY( currentEntry );
- numEntriesWritten++;
- }
-
- // Third, if we are using the cache file, write the old entries
- // that were not used this time around.
-
- if ((data->state & Data::UsingCacheFile) != 0)
- {
- // First, write the ones that we already have partially loaded
-
- iter = data->oldCacheEntries->Iterate();
-
- while (iter.Next() && amountWritten < MAX_CACHEFILE_SIZE)
- {
- CacheEntry* currentEntry = (CacheEntry*)iter.GetElement();
-
- if (!currentEntry->used)
- {
- if(!WriteEntry( cache, currentEntry, data->cache ))
- {
- goto CLEANUP;
- }
-
- amountWritten += SIZE_OF_ENTRY( currentEntry );
- numEntriesWritten++;
- }
- }
-
- while (amountWritten < MAX_CACHEFILE_SIZE)
- {
- CacheEntry* entry = LoadNextEntry( data->cache, data );
-
- if (entry == NULL)
- break;
-
- if (!WriteEntry( cache, entry, data->cache ))
- {
- goto CLEANUP;
- }
-
- amountWritten += SIZE_OF_ENTRY( entry );
- numEntriesWritten++;
- }
- }
-
- fWriteSucceeded = TRUE;
- }
-
-
- if (!fWriteSucceeded)
- {
- CloseHandle( cache.GetValue() );
- cache.SuppressRelease();
- WszDeleteFile( newFileName );
- goto CLEANUP;
- }
-
- // End with writing the header.
-
- header.configFileTime = data->configFileTime;
- header.isSecurityOn = 1;
- header.numEntries = numEntriesWritten;
- header.quickCache = data->header.quickCache;
- header.sizeConfig = sizeConfig;
-
- if (SetFilePointer( cache, 0, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- {
- // Couldn't move to the beginning of the file
- goto CLEANUP;
- }
-
- if (WriteFileData( cache, (PBYTE)&header, sizeof( header ) ) != S_OK)
- {
- // Couldn't write header info.
- goto CLEANUP;
- }
-
- if (sizeConfig != 0)
- {
- if ((data->state & Data::NewConfigFile) != 0)
- {
- if (WriteFileData( cache, data->configBuffer, sizeConfig ) != S_OK)
- {
- goto CLEANUP;
- }
- }
- else
- {
- if (data->configData != NULL)
- {
- if (WriteFileData( cache, data->configData, sizeConfig ) != S_OK)
- {
- goto CLEANUP;
- }
- }
- else if ((data->state & Data::UsingCacheFile) != 0)
- {
- configBuffer.Assign( new BYTE[sizeConfig] );
-
- if (SetFilePointer( data->cache, sizeof( CacheHeader ), NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- {
- goto CLEANUP;
- }
-
- if (ReadFileData( data->cache, configBuffer.GetValue(), sizeConfig ) != S_OK)
- {
- goto CLEANUP;
- }
-
- if (WriteFileData( cache, configBuffer.GetValue(), sizeConfig ) != S_OK)
- {
- goto CLEANUP;
- }
- }
- else
- {
- configBuffer.Assign( new BYTE[sizeConfig] );
-
- if (SetFilePointer( config, 0, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- {
- goto CLEANUP;
- }
-
- if (ReadFileData( config, configBuffer.GetValue(), sizeConfig ) != S_OK)
- {
- goto CLEANUP;
- }
-
- if (WriteFileData( cache, configBuffer.GetValue(), sizeConfig ) != S_OK)
- {
- goto CLEANUP;
- }
- }
- }
- }
-
- // Flush the file buffers to make sure
- // we get full write through.
-
- FlushFileBuffers( cache.GetValue() );
-
- CloseHandle( cache );
- cache.SuppressRelease();
- CloseHandle( data->cache );
- data->cache = INVALID_HANDLE_VALUE;
-
- // Move the existing file out of the way
- // Note: use MoveFile because we know it will never cross
- // device boundaries.
-
- // Note: the delete file can fail, but we can't really do anything
- // if it does so just ignore any failures.
- WszDeleteFile( data->cacheFileNameTemp );
-
- // Try to move the existing cache file out of the way. However, if we can't
- // then try to delete it. If it can't be deleted then just bail out.
- if (!WszMoveFile( data->cacheFileName, data->cacheFileNameTemp ) &&
- (!Assembly::FileNotFound(HRESULT_FROM_WIN32(GetLastError()))) &&
- !WszDeleteFile( data->cacheFileName ))
- {
- if (!Assembly::FileNotFound(HRESULT_FROM_WIN32(GetLastError())))
- goto CLEANUP;
- }
-
- // Move the new file into position
-
- if (!WszMoveFile( newFileName, data->cacheFileName ))
- {
- goto CLEANUP;
- }
-
- retval = TRUE;
-
-CLEANUP:
- if (retval)
- cache.SuppressRelease();
-
- return retval;
-
-}
-
-void QCALLTYPE SecurityConfig::ResetCacheData(INT32 id)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- Data* data = (Data*)GetData( id );
-
- if (data != NULL)
- {
- CrstHolder ch(&dataLock_);
-
- data->DeleteAllEntries();
-
- data->oldCacheEntries = new ArrayList;
- data->newCacheEntries = new ArrayList;
-
- data->header = CacheHeader();
- data->state = (Data::State)(~(Data::CopyCacheFile | Data::UsingCacheFile) & data->state);
-
- HandleHolder config(WszCreateFile( data->configFileName, GENERIC_READ, GetShareFlags(), NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ));
-
- if (config.GetValue() != INVALID_HANDLE_VALUE)
- {
- VERIFY(GetFileTime( config, NULL, NULL, &data->configFileTime ));
- VERIFY(GetFileTime( config, NULL, NULL, &data->header.configFileTime ));
- }
-}
-
- END_QCALL;
-}
-
-HRESULT QCALLTYPE SecurityConfig::SaveDataByte(LPCWSTR wszConfigPath, LPCBYTE pbData, DWORD cbData)
-{
- QCALL_CONTRACT;
-
- HRESULT retval = E_FAIL;
-
- BEGIN_QCALL;
-
- HandleHolder newFile(INVALID_HANDLE_VALUE);
-
- int RetryCount;
- DWORD error = 0;
- DWORD fileNameLength = (DWORD) wcslen(wszConfigPath);
-
- NewArrayHolder<WCHAR> newFileName(new WCHAR[fileNameLength + 5]);
- NewArrayHolder<WCHAR> oldFileName(new WCHAR[fileNameLength + 5]);
-
- swprintf_s( newFileName.GetValue(), fileNameLength + 5, W("%s%s"), wszConfigPath, W(".new") );
- swprintf_s( oldFileName.GetValue(), fileNameLength + 5, W("%s%s"), wszConfigPath, W(".old") );
-
- // Create the new file.
- for (RetryCount = 0; RetryCount < 5; RetryCount++) {
- newFile.Assign( WszCreateFile( newFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ) );
-
- if (newFile != INVALID_HANDLE_VALUE)
- break;
- else
- {
- error = GetLastError();
-
- if (error == ERROR_PATH_NOT_FOUND)
- {
- // The directory does not exist, iterate through and try to create it.
-
- WCHAR* currentChar = newFileName;
-
- // Skip the first backslash
-
- while (*currentChar != W('\0'))
- {
- if (*currentChar == W('\\') || *currentChar == W('/'))
- {
- currentChar++;
- break;
- }
- currentChar++;
- }
-
- // Iterate through trying to create each subdirectory.
-
- while (*currentChar != W('\0'))
- {
- if (*currentChar == W('\\') || *currentChar == W('/'))
- {
- *currentChar = W('\0');
-
- if (!WszCreateDirectory( newFileName, NULL ))
- {
- error = GetLastError();
-
- if (error != ERROR_ACCESS_DENIED && error != ERROR_ALREADY_EXISTS)
- {
- goto CLEANUP;
- }
- }
-
- *currentChar = W('\\');
- }
- currentChar++;
- }
-
- // Try the file creation again
- continue;
- }
- }
-
- // CreateFile failed. Sleep a little and retry, in case a
- // virus scanner caused the creation to fail.
- ClrSleepEx(10, FALSE);
- }
-
- if (newFile == INVALID_HANDLE_VALUE) {
- goto CLEANUP;
- }
-
- // Write the data into it.
- if ((retval = WriteFileData(newFile.GetValue(), pbData, cbData)) != S_OK)
- {
- // Write failed, destroy the file and bail.
- // Note: if the delete fails, we always do a CREATE_NEW
- // for this file so that should take care of it. If not
- // we'll fail to write out future cache files.
- CloseHandle( newFile.GetValue() );
- newFile.SuppressRelease();
- WszDeleteFile( newFileName );
- goto CLEANUP;
- }
-
- if (!FlushFileBuffers(newFile.GetValue()))
- {
- error = GetLastError();
- goto CLEANUP;
- }
-
- CloseHandle( newFile.GetValue() );
- newFile.SuppressRelease();
-
- // Move the existing file out of the way
- if (!WszMoveFileEx( wszConfigPath, oldFileName, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED ))
- {
- // If move fails for a reason other than not being able to find the file, bail out.
- // Also, if the old file didn't exist, we have no need to delete it.
- HRESULT hrMove = HRESULT_FROM_WIN32(GetLastError());
- if (!Assembly::FileNotFound(hrMove))
- {
- retval = hrMove;
- WszDeleteFile(wszConfigPath);
- goto CLEANUP;
- }
- }
-
- // Move the new file into position
-
- if (!WszMoveFileEx( newFileName, wszConfigPath, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED ))
- {
- error = GetLastError();
- goto CLEANUP;
- }
-
- retval = S_OK;
-
-CLEANUP:
- if (retval == E_FAIL && error != 0)
- retval = HRESULT_FROM_WIN32(error);
-
- END_QCALL;
-
- return retval;
-}
-
-BOOL QCALLTYPE SecurityConfig::RecoverData(INT32 id)
- {
- QCALL_CONTRACT;
-
- BOOL retval = FALSE;
-
- BEGIN_QCALL;
-
- Data* data = (Data*)GetData( id );
-
- if (data == NULL)
- goto CLEANUP;
-
- {
- DWORD fileNameLength = (DWORD)wcslen( data->configFileName );
-
- NewArrayHolder<WCHAR> tempFileName(new WCHAR[fileNameLength + 10]);
- NewArrayHolder<WCHAR> oldFileName(new WCHAR[fileNameLength + 5]);
-
- swprintf_s( tempFileName.GetValue(), fileNameLength + 10, W("%s%s"), data->configFileName, W(".old.temp") );
- swprintf_s( oldFileName.GetValue(), fileNameLength + 5, W("%s%s"), data->configFileName, W(".old") );
-
- HandleHolder oldFile(WszCreateFile( oldFileName, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ));
-
- if (oldFile.GetValue() == INVALID_HANDLE_VALUE)
- {
- goto CLEANUP;
- }
-
- CloseHandle( oldFile );
- oldFile.SuppressRelease();
-
- if (!WszMoveFile( data->configFileName, tempFileName ))
- {
- goto CLEANUP;
- }
-
- if (!WszMoveFile( oldFileName, data->configFileName ))
- {
- goto CLEANUP;
- }
-
- if (!WszMoveFile( tempFileName, oldFileName ))
- {
- goto CLEANUP;
- }
- }
-
- // We need to do some work to reset the unmanaged data object
- // so that the managed side of things behaves like you'd expect.
- // This basically means cleaning up the open resources and
- // doing the work to init on a different set of files.
-
- data->Reset();
- InitData( data, FALSE );
-
- retval = TRUE;
-
-CLEANUP:
- END_QCALL;
-
- return retval;
-}
-
-BOOL SecurityConfig::GetQuickCacheEntry( INT32 id, QuickCacheEntryType type )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END
-
- //
- // If there is no config file for this level, then we'll assume the default
- // security policy is in effect. This could happen for example if there is
- // user profile loaded or if the config file is not present.
- //
-
- Data* data = (Data*)GetData( id );
- if (data == NULL || ((data->state & Data::UsingConfigFile) == 0))
- return (type == FullTrustZoneMyComputer); // MyComputer gets FT by default.
-
- if ((data->state & Data::UsingCacheFile) == 0)
- return FALSE;
-
- return (data->header.quickCache & type);
-}
-
-void QCALLTYPE SecurityConfig::SetQuickCache(INT32 id, QuickCacheEntryType type)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- Data* data = (Data*)GetData( id );
-
- if (data != NULL && (DWORD) type != data->header.quickCache)
- {
- CrstHolder ch(&dataLock_);
-
- data->state = (Data::State)(Data::CacheUpdated | data->state);
- data->header.quickCache = type;
- }
-
- END_QCALL;
-}
-
-static HANDLE OpenCacheFile( Data* data )
-{
- STANDARD_VM_CONTRACT;
-
- CrstHolder ch(&SecurityConfig::dataLock_);
-
- if (data->cache != INVALID_HANDLE_VALUE)
- return data->cache;
-
- _ASSERTE( FALSE && "This case should never happen" );
-
- data->cache = WszCreateFile( data->cacheFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
- if (data->cache == INVALID_HANDLE_VALUE)
- return NULL;
-
- // Check whether the cache has changed since we first looked at it.
- // If it has but the config file hasn't, then we need to start fresh.
- // However, if the config file has changed then we have to ignore it.
-
- if (CacheOutOfDate( &data->cacheFileTime, data->cache, NULL ))
- {
- if (CacheOutOfDate( &data->configFileTime, data->configFileName, NULL ))
- return NULL;
-
- if (ReadFileData( data->cache, (BYTE*)&data->header, sizeof( CacheHeader ) ) != S_OK)
- return NULL;
-
- data->cacheCurrentPosition = sizeof( CacheHeader );
-
- if (data->oldCacheEntries != NULL)
- {
- ArrayList::Iterator iter = data->oldCacheEntries->Iterate();
- while (iter.Next())
- {
- delete (CacheEntry*)iter.GetElement();
- }
- delete data->oldCacheEntries;
- data->oldCacheEntries = new ArrayList();
- }
- }
-
- return data->cache;
-}
-
-static BYTE* CompareEntry( CacheEntry* entry, DWORD numEvidence, DWORD evidenceSize, LPCBYTE evidenceBlock, HANDLE cache, DWORD* size)
-{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE (entry);
-
- if (entry->header.numItemsInKey == numEvidence &&
- entry->header.keySize == evidenceSize)
- {
- if (entry->key == NULL)
- {
- // We were lazy in reading the entry. Read the key now.
- entry->key = new BYTE[entry->header.keySize];
-
- _ASSERTE (cache != INVALID_HANDLE_VALUE);
-
- if (SetFilePointer( cache, entry->cachePosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- return NULL;
-
- if (ReadFileData( cache, entry->key, entry->header.keySize ) != S_OK)
- return NULL;
-
- entry->cachePosition += entry->header.keySize;
- }
-
- _ASSERTE (entry->key);
-
- if (memcmp( entry->key, evidenceBlock, entry->header.keySize ) == 0)
- {
- if (entry->data == NULL)
- {
- // We were lazy in reading the entry. Read the data also.
- entry->data = new BYTE[entry->header.dataSize];
-
- if (SetFilePointer( cache, entry->cachePosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- return NULL;
-
- if (ReadFileData( cache, entry->data, entry->header.dataSize ) != S_OK)
- return NULL;
-
- entry->cachePosition += entry->header.dataSize;
- }
-
- entry->used = TRUE;
- *size = entry->header.dataSize;
-
- return entry->data;
- }
- }
- return NULL;
-}
-
-BOOL QCALLTYPE SecurityConfig::GetCacheEntry(INT32 id, DWORD numEvidence, LPCBYTE pEvidence, DWORD cbEvidence, QCall::ObjectHandleOnStack retPolicy)
-{
- QCALL_CONTRACT;
-
- BOOL success = FALSE;
-
- BEGIN_QCALL;
-
- HANDLE cache = INVALID_HANDLE_VALUE;
-
- BYTE* retval = NULL;
- DWORD size = (DWORD) -1;
-
- Data* data = (Data*)GetData( id );
-
- if (data == NULL)
- {
- goto CLEANUP;
- }
-
- {
-
- ArrayList::Iterator iter;
-
- if ((data->state & Data::UsingCacheFile) == 0)
- {
- // We know we don't have anything in the config file, so
- // let's just look through the new entries to make sure we
- // aren't getting any repeats.
-
- // Then try the existing new entries
-
- iter = data->newCacheEntries->Iterate();
-
- while (iter.Next())
- {
- // newCacheEntries do not need the cache file so pass in NULL.
- retval = CompareEntry( (CacheEntry*)iter.GetElement(), numEvidence, cbEvidence, pEvidence, NULL, &size );
-
- if (retval != NULL)
- {
- success = TRUE;
- goto CLEANUP;
- }
- }
-
- goto CLEANUP;
- }
-
- // Its possible that the old entries were not read in completely
- // so we keep the cache file open before iterating through the
- // old entries.
-
- cache = OpenCacheFile( data );
-
- if ( cache == NULL )
- {
- goto CLEANUP;
- }
-
- // First, iterator over the old entries
-
- {
- CrstHolder ch(&dataLock_);
-
- iter = data->oldCacheEntries->Iterate();
- while (iter.Next())
- {
- retval = CompareEntry( (CacheEntry*)iter.GetElement(), numEvidence, cbEvidence, pEvidence, cache, &size );
- if (retval != NULL)
- {
- success = TRUE;
- goto CLEANUP;
- }
- }
-
- // LockHolder goes out of scope here
- }
-
- // Then try the existing new entries
- iter = data->newCacheEntries->Iterate();
- while (iter.Next())
- {
- // newCacheEntries do not need the cache file so pass in NULL.
- retval = CompareEntry( (CacheEntry*)iter.GetElement(), numEvidence, cbEvidence, pEvidence, NULL, &size );
- if (retval != NULL)
- {
- success = TRUE;
- goto CLEANUP;
- }
- }
-
- // Finally, try loading existing entries from the file
-
- {
- CrstHolder ch(&dataLock_);
-
- if (SetFilePointer( cache, data->cacheCurrentPosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- {
- goto CLEANUP;
- }
-
- do
- {
- CacheEntry* entry = LoadNextEntry( cache, data );
- if (entry == NULL)
- {
- data->state = (Data::State)(Data::CacheExhausted | data->state);
- break;
- }
-
- retval = CompareEntry( entry, numEvidence, cbEvidence, pEvidence, cache, &size );
- if (retval != NULL)
- {
- success = TRUE;
- break;
- }
- } while (TRUE);
-
- // LockHolder goes out of scope here
- }
- }
-
-CLEANUP:
- if (success && retval != NULL)
- {
- _ASSERTE( size != (DWORD) -1 );
- retPolicy.SetByteArray(retval, size);
- }
-
- END_QCALL;
-
- return success;
-}
-
-void QCALLTYPE SecurityConfig::AddCacheEntry(INT32 id, DWORD numEvidence, LPCBYTE pEvidence, DWORD cbEvidence, LPCBYTE pPolicy, DWORD cbPolicy)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- Data* data = (Data*)GetData( id );
-
- DWORD sizeOfEntry = 0;
- NewHolder<CacheEntry> entry;
-
- if (data == NULL)
- {
- goto lExit;
- }
-
- // In order to limit how large a long running app can become,
- // we limit the total memory held by the new cache entries list.
- // For now this limit corresponds with how large the max cache file
- // can be.
-
- sizeOfEntry = cbEvidence + cbPolicy + sizeof( CacheEntryHeader );
-
- if (data->newEntriesSize + sizeOfEntry >= MAX_CACHEFILE_SIZE)
- {
- goto lExit;
- }
-
- entry = new CacheEntry();
-
- entry->header.numItemsInKey = numEvidence;
- entry->header.keySize = cbEvidence;
- entry->header.dataSize = cbPolicy;
-
- entry->key = new BYTE[entry->header.keySize];
- entry->data = new BYTE[entry->header.dataSize];
-
- memcpyNoGCRefs(entry->key, pEvidence, cbEvidence);
- memcpyNoGCRefs(entry->data, pPolicy, cbPolicy);
-
- {
- CrstHolder ch(&dataLock_);
-
- // Check the size again to handle the race.
- if (data->newEntriesSize + sizeOfEntry < MAX_CACHEFILE_SIZE)
- {
- data->state = (Data::State)(Data::CacheUpdated | data->state);
- IfFailThrow(data->newCacheEntries->Append( entry.GetValue() ));
- entry.SuppressRelease();
- data->newEntriesSize += sizeOfEntry;
- }
- }
-
-lExit: ;
-
- END_QCALL;
-}
-
-ArrayListStatic SecurityConfig::entries_;
-CrstStatic SecurityConfig::dataLock_;
-
-void SecurityConfig::Init( void )
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END
-
- dataLock_.Init(CrstSecurityPolicyCache);
- entries_.Init();
-}
-
-void SecurityConfig::Cleanup( void )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END
-
- ArrayList::Iterator iter = entries_.Iterate();
-
- GCX_PREEMP();
-
- CrstHolder ch(&dataLock_);
-
- while (iter.Next())
- {
- ((Data*) iter.GetElement())->Cleanup();
- }
-}
-
-void SecurityConfig::Delete( void )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END
-
- ArrayList::Iterator iter = entries_.Iterate();
-
- while (iter.Next())
- {
- delete (Data*) iter.GetElement();
- }
-
- entries_.Destroy();
- dataLock_.Destroy();
-}
-
-void QCALLTYPE SecurityConfig::_GetMachineDirectory(QCall::StringHandleOnStack retDirectory)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- WCHAR machine[MAX_LONGPATH];
-
- HRESULT hr = GetMachineDirectory(machine, MAX_LONGPATH);
- if (FAILED(hr))
- ThrowHR(hr);
-
- retDirectory.Set(machine);
-
- END_QCALL;
-}
-
-void QCALLTYPE SecurityConfig::_GetUserDirectory(QCall::StringHandleOnStack retDirectory)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- WCHAR user[MAX_LONGPATH];
-
- BOOL result = GetUserDirectory(user, MAX_LONGPATH);
- if (result)
- retDirectory.Set(user);
-
- END_QCALL;
-}
-
-HRESULT SecurityConfig::GetMachineDirectory(__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr;
-
- DWORD length = (DWORD)bufferCount;
- hr = GetInternalSystemDirectory(buffer, &length);
- if (FAILED(hr))
- return hr;
-
- // Make sure we have enough buffer to concat the string.
- // Note the length including the terminating zero.
- if((bufferCount - wcslen(buffer) - 1) < wcslen(W("config\\")))
- return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
-
- wcscat_s(buffer, bufferCount, W("config\\"));
-
- return S_OK;
-}
-
-BOOL SecurityConfig::GetVIUserDirectory(__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount)
-{
- STANDARD_VM_CONTRACT;
-
- WCHAR scratchBuffer[MAX_LONGPATH];
- BOOL retval = FALSE;
-
- DWORD size = MAX_LONGPATH;
-
- if (!GetUserDir(buffer, bufferCount, TRUE))
- goto CLEANUP;
-
- wcscpy_s( scratchBuffer, COUNTOF(scratchBuffer), W("\\Microsoft\\CLR Security Config\\") );
-
- if (bufferCount < wcslen( buffer ) + wcslen( scratchBuffer ) + 1)
- {
- goto CLEANUP;
- }
-
- wcscat_s( buffer, bufferCount, scratchBuffer );
-
- retval = TRUE;
-
-CLEANUP:
- return retval;
-}
-
-BOOL SecurityConfig::GetUserDirectory(__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount)
-{
- STANDARD_VM_CONTRACT;
-
- StackSString ssScratchBuffer;
- BOOL retval = FALSE;
-
- WCHAR* wszScratchBuffer = ssScratchBuffer.OpenUnicodeBuffer( (COUNT_T)bufferCount );
- retval = GetVIUserDirectory(wszScratchBuffer, bufferCount);
- ssScratchBuffer.CloseBuffer( (COUNT_T)wcslen( wszScratchBuffer ) );
-
- if (!retval)
- return retval;
-
- ssScratchBuffer.Append( W("v") );
- ssScratchBuffer.Append( VER_PRODUCTVERSION_NO_QFE_STR_L );
- ssScratchBuffer.Append( W("\\") );
-
-#ifdef _WIN64
- ssScratchBuffer.Append( W("64bit\\") );
-#endif // _WIN64
-
- if (ssScratchBuffer.GetCount() + 1 > bufferCount)
- return FALSE;
-
- wcscpy_s( buffer, bufferCount, ssScratchBuffer.GetUnicode() );
-
- return TRUE;
-}
-
-BOOL QCALLTYPE SecurityConfig::WriteToEventLog(LPCWSTR wszMessage)
-{
- QCALL_CONTRACT;
-
- BOOL retVal = FALSE;
-
- BEGIN_QCALL;
-
- retVal = ReportEventCLR(
- EVENTLOG_WARNING_TYPE, // event type
- 0, // category
- (DWORD)1000, // event identifier
- NULL, // no user security identifier
- &StackSString(wszMessage)); // message to log
-
- END_QCALL
-
- return retVal;
-}
-
-#ifdef _DEBUG
-HRESULT QCALLTYPE SecurityConfig::DebugOut(LPCWSTR wszFileName, LPCWSTR wszMessage)
-{
- HRESULT retVal = E_FAIL;
-
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- HandleHolder file(WszCreateFile( wszFileName, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ));
-
- if (file == INVALID_HANDLE_VALUE)
- {
- goto lExit;
- }
-
- SetFilePointer( file, 0, NULL, FILE_END );
-
- DWORD cbMessage;
- DWORD cbWritten;
-
- cbMessage = (DWORD)wcslen(wszMessage) * sizeof(WCHAR);
- if (!WriteFile( file, wszMessage, cbMessage, &cbWritten, NULL ))
- {
- goto lExit;
- }
-
- if (cbMessage != cbWritten)
- {
- goto lExit;
- }
-
- retVal = S_OK;
-
-lExit: ;
- END_QCALL;
-
- return retVal;
-}
-#endif
-
-#endif // FEATURE_CAS_POLICY
+++ /dev/null
-// 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.
-//
-// File: SecurityConfig.h
-//
-
-//
-// Native implementation for security config access and manipulation
-//
-
-
-#ifndef _COMSecurityConfig_H_
-#define _COMSecurityConfig_H_
-#ifdef FEATURE_CAS_POLICY
-
-#include "qcall.h"
-
-class SecurityConfig
-{
-friend struct CacheHeader;
-
-private:
- // These structures can be removed in the next SxS runtime version when we won't have to potentially read
- // config files generated by an in-place runtime that used to include them in the header.
- enum RegistryExtensionsAccessStatus {
- Unknown = 0,
- NoExtensions = 1,
- AccessFailure = 2,
- AccessSuccess = 3
- };
-
- struct RegistryExtensionsInfo {
- RegistryExtensionsAccessStatus eStatus;
- FILETIME ftLastWriteTime;
- };
-
-public:
- // Duplicated in System.Security.Util.Config.cs
- enum ConfigId
- {
- None = 0,
- MachinePolicyLevel = 1,
- UserPolicyLevel = 2,
- EnterprisePolicyLevel = 3,
- };
-
- // Duplicated in System.Security.Util.Config.cs
- enum QuickCacheEntryType
- {
- FullTrustZoneMyComputer = 0x1000000,
- FullTrustZoneIntranet = 0x2000000,
- FullTrustZoneInternet = 0x4000000,
- FullTrustZoneTrusted = 0x8000000,
- FullTrustZoneUntrusted = 0x10000000,
- FullTrustAll = 0x20000000,
- };
-
- // Duplicated in System.Security.Util.Config.cs
- enum ConfigRetval
- {
- NoFile = 0,
- ConfigFile = 1,
- CacheFile = 2
- };
-
- static ConfigRetval InitData( INT32 id, const WCHAR* configFileName, const WCHAR* cacheFileName );
- static ConfigRetval InitData( void* configData, BOOL addToList );
-
- static BOOL SaveCacheData( INT32 id );
-
- static
- void QCALLTYPE ResetCacheData(INT32 id);
-
- static
- HRESULT QCALLTYPE SaveDataByte(LPCWSTR wszConfigPath, LPCBYTE pbData, DWORD cbData);
-
- static
- BOOL QCALLTYPE RecoverData(INT32 id);
-
- static
- void QCALLTYPE SetQuickCache(INT32 id, QuickCacheEntryType type);
-
- static
- BOOL QCALLTYPE GetCacheEntry(INT32 id, DWORD numEvidence, LPCBYTE pEvidence, DWORD cbEvidence, QCall::ObjectHandleOnStack retPolicy);
-
- static
- void QCALLTYPE AddCacheEntry(INT32 id, DWORD numEvidence, LPCBYTE pEvidence, DWORD cbEvidence, LPCBYTE pPolicy, DWORD cbPolicy);
-
- static
- void QCALLTYPE _GetMachineDirectory(QCall::StringHandleOnStack retDirectory);
-
- static
- void QCALLTYPE _GetUserDirectory(QCall::StringHandleOnStack retDirectory);
-
- static HRESULT GetMachineDirectory (__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount);
- static BOOL GetUserDirectory(__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount);
- static BOOL GetVIUserDirectory(__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount);
-
- static
- BOOL QCALLTYPE WriteToEventLog(LPCWSTR wszMessage);
-
-#ifdef _DEBUG
- static
- HRESULT QCALLTYPE DebugOut(LPCWSTR wszFileName, LPCWSTR wszMessage);
-#endif
-
- static void Init( void );
- static void Cleanup( void );
- static void Delete( void );
-
- static BOOL GetQuickCacheEntry( INT32 id, QuickCacheEntryType type );
-
- static void* GetData( INT32 id );
-
- static ArrayListStatic entries_;
- static CrstStatic dataLock_;
-
- static WCHAR* wcscatDWORD( __out_ecount(cchdst) __out_z WCHAR* dst, size_t cchdst, DWORD num );
-};
-#endif // FEATURE_CAS_POLICY
-#endif
break;
case DS_UNION:
-#ifdef FEATURE_CAS_POLICY
- LinkNewDeclAction(ppActionList, action, SecurityAttributes::MergePermissionSets(pClassPCE, pMethodPCE, false, action), pMeth);
-#else // FEATURE_CAS_POLICY
_ASSERTE(!"Declarative permission sets may not be unioned together in CoreCLR. Are you attempting to have a declarative demand or deny on both a method and its enclosing class?");
-#endif // FEATURE_CAS_POLICY
break;
case DS_INTERSECT:
-#ifdef FEATURE_CAS_POLICY
- LinkNewDeclAction(ppActionList, action, SecurityAttributes::MergePermissionSets(pClassPCE, pMethodPCE, true, action), pMeth);
-#else // FEATURE_CAS_POLICY
_ASSERTE(!"Declarative permission sets may not be intersected in CoreCLR. Are you attempting to have a declarative permit only on both a method and its enclosing class?");
-#endif // FEATURE_CAS_POLICY
break;
case DS_APPLY_METHOD_THEN_CLASS:
if (pClass->HasSuppressUnmanagedCodeAccessAttr())
{
-#ifdef FEATURE_CORECLR
hr = S_OK;
-#else
- hr = pInternalImport->GetCustomAttributeByName(pMT->GetCl(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL);
-#endif // FEATURE_CORECLR
if (hr != S_OK)
{
g_IBCLogger.LogEEClassCOWTableAccess(pMT);
BOOL hasSuppressUnmanagedCodeAccessAttr;
if (pfHasSuppressUnmanagedCodeAccessAttr == NULL)
{
-#ifdef FEATURE_CORECLR
hasSuppressUnmanagedCodeAccessAttr = TRUE;
-#else
- hasSuppressUnmanagedCodeAccessAttr =
- (pInternalImport->GetCustomAttributeByName(token,
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK);
-#endif
}
else
hasSuppressUnmanagedCodeAccessAttr = *pfHasSuppressUnmanagedCodeAccessAttr;
//
//-----------------------------------------------------------------------------
-#ifdef FEATURE_APTCA
-void DECLSPEC_NORETURN SecurityDeclarative::ThrowAPTCAException(Assembly *pCaller, MethodDesc *pCallee)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- MethodDescCallSite throwSecurityException(METHOD__SECURITY_ENGINE__THROW_SECURITY_EXCEPTION);
-
- OBJECTREF callerObj = NULL;
- if (pCaller != NULL && pCaller->GetDomain() == GetAppDomain())
- callerObj = pCaller->GetExposedObject();
-
- ARG_SLOT args[7];
- args[0] = ObjToArgSlot(callerObj);
- args[1] = ObjToArgSlot(NULL);
- args[2] = ObjToArgSlot(NULL);
- args[3] = PtrToArgSlot(pCallee);
- args[4] = (ARG_SLOT)dclLinktimeCheck;
- args[5] = ObjToArgSlot(NULL);
- args[6] = ObjToArgSlot(NULL);
- throwSecurityException.Call(args);
-
- UNREACHABLE();
-}
-#endif // FEATURE_APTCA
-
-#ifdef FEATURE_CAS_POLICY
-void DECLSPEC_NORETURN SecurityDeclarative::ThrowHPException(EApiCategories protectedCategories, EApiCategories demandedCategories)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- OBJECTREF hpException = NULL;
- GCPROTECT_BEGIN(hpException);
-
- MethodTable* pMT = MscorlibBinder::GetClass(CLASS__HOST_PROTECTION_EXCEPTION);
- hpException = (OBJECTREF) AllocateObject(pMT);
-
-
- MethodDescCallSite ctor(METHOD__HOST_PROTECTION_EXCEPTION__CTOR);
-
- ARG_SLOT arg[3] = {
- ObjToArgSlot(hpException),
- protectedCategories,
- demandedCategories
- };
- ctor.Call(arg);
-
- COMPlusThrow(hpException);
-
- GCPROTECT_END();
-}
-#endif // FEATURE_CAS_POLICY
-
-#ifdef FEATURE_APTCA
-BOOL SecurityDeclarative::IsUntrustedCallerCheckNeeded(MethodDesc *pCalleeMD, Assembly *pCallerAssem)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- Assembly *pCalleeAssembly = pCalleeMD->GetAssembly();
- _ASSERTE(pCalleeAssembly != NULL);
-
- // ATPCA is only enforced for cross-assembly calls, so if the target is not accessable from outside
- // the assembly, or if the caller and callee are both within the same assembly, we do not need to
- // do any APTCA checks
- if (pCallerAssem == pCalleeAssembly)
- {
- return FALSE;
- }
-
- if (!MethodIsVisibleOutsideItsAssembly(pCalleeMD))
- {
- return FALSE;
- }
-
- // If the target assembly allows untrusted callers unconditionally, then the call should be allowed
- if (pCalleeAssembly->AllowUntrustedCaller())
- {
- return FALSE;
- }
-
- // Otherwise, we need to ensure the caller is fully trusted
- return TRUE;
-}
-#endif // FEATURE_APTCA
-
-#ifdef FEATURE_APTCA
-// Do a fulltrust check on the caller if the callee is fully trusted and
-// callee did not enable AllowUntrustedCallerChecks
-/*static*/
-void SecurityDeclarative::DoUntrustedCallerChecks(
- Assembly *pCaller, MethodDesc *pCallee,
- BOOL fFullStackWalk)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
- BOOL fRet = TRUE;
-#ifdef _DEBUG
- if (!g_pConfig->Do_AllowUntrustedCaller_Checks())
- return;
-#endif
-
- if (!IsUntrustedCallerCheckNeeded(pCallee, pCaller))
- return;
-
- // Expensive calls after this point, this could end up resolving policy
-
- if (fFullStackWalk)
- {
- // It is possible that wrappers like VBHelper libraries that are
- // fully trusted, make calls to public methods that do not have
- // safe for Untrusted caller custom attribute set.
- // Like all other link demand that gets transformed to a full stack
- // walk for reflection, calls to public methods also gets
- // converted to full stack walk
-
- OBJECTREF permSet = NULL;
- GCPROTECT_BEGIN(permSet);
-
- GetPermissionInstance(&permSet, SECURITY_FULL_TRUST);
- EX_TRY
- {
- SecurityStackWalk::DemandSet(SSWT_LATEBOUND_LINKDEMAND, permSet);
- }
- EX_CATCH
- {
- fRet = FALSE;
- }
- EX_END_CATCH(RethrowTerminalExceptions);
-
- GCPROTECT_END();
- }
- else
- {
- _ASSERTE(pCaller);
-
- // Link Demand only, no full stack walk here
- if (!pCaller->GetSecurityDescriptor()->IsFullyTrusted())
- fRet = FALSE;
- }
-
- if (!fRet)
- {
- ThrowAPTCAException(pCaller, pCallee);
- }
-}
-#endif // FEATURE_APTCA
// Retrieve all linktime demands sets for a method. This includes both CAS and
// non-CAS sets for LDs at the class and the method level, so we could get up to
INJECT_FAULT(COMPlusThrowOM(););
} CONTRACTL_END;
-#ifdef FEATURE_CAS_POLICY
- MethodTable * pMT = pMD->GetMethodTable();
-
- // Class level first.
- if (pMT->GetClass()->RequiresLinktimeCheck())
- *pClassCas = TypeSecurityDescriptor::GetLinktimePermissions(pMT, pClassNonCas);
-
- // Then the method level.
- if (IsMdHasSecurity(pMD->GetAttrs()))
- *pMethodCas = MethodSecurityDescriptor::GetLinktimePermissions(pMD, pMethodNonCas);
-#endif
}
//
return reason;
}
-#ifdef FEATURE_CAS_POLICY
-// Issue an inheritance demand against the target assembly
-
-// static
-void SecurityDeclarative::InheritanceDemand(Assembly *pTargetAssembly, OBJECTREF refDemand)
-{
- CONTRACTL
- {
- THROWS;
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- PRECONDITION(CheckPointer(pTargetAssembly));
- PRECONDITION(refDemand != NULL);
- }
- CONTRACTL_END;
-
- struct
- {
- OBJECTREF refDemand;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
- gc.refDemand = refDemand;
-
- GCPROTECT_BEGIN(gc);
-
- IAssemblySecurityDescriptor *pTargetASD = pTargetAssembly->GetSecurityDescriptor();
- SecurityStackWalk::LinkOrInheritanceCheck(pTargetASD,
- gc.refDemand,
- pTargetAssembly,
- dclInheritanceCheck);
- GCPROTECT_END();
-}
-
-// static
-void SecurityDeclarative::InheritanceLinkDemandCheck(Assembly *pTargetAssembly, MethodDesc * pMDLinkDemand)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pTargetAssembly));
- PRECONDITION(CheckPointer(pMDLinkDemand));
- }
- CONTRACTL_END;
-
- GCX_COOP();
- struct
- {
- OBJECTREF refClassCas;
- OBJECTREF refClassNonCas;
- OBJECTREF refMethodCas;
- OBJECTREF refMethodNonCas;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- Security::RetrieveLinktimeDemands(pMDLinkDemand,
- &gc.refClassCas,
- &gc.refClassNonCas,
- &gc.refMethodCas,
- &gc.refMethodNonCas);
-
- if (gc.refClassCas != NULL)
- {
- InheritanceDemand(pTargetAssembly, gc.refClassCas);
- }
-
- if (gc.refMethodCas != NULL)
- {
- InheritanceDemand(pTargetAssembly, gc.refMethodCas);
- }
-
- GCPROTECT_END();
-}
-
-// Issue a FullTrust inheritance demand against the target assembly
-
-// static
-void SecurityDeclarative::FullTrustInheritanceDemand(Assembly *pTargetAssembly)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pTargetAssembly));
- }
- CONTRACTL_END;
-
- GCX_COOP();
-
- struct
- {
- OBJECTREF refFullTrust;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.refFullTrust = Security::CreatePermissionSet(TRUE);
- InheritanceDemand(pTargetAssembly, gc.refFullTrust);
-
- GCPROTECT_END();
-}
-
-// Issue a FullTrust link demand against the target assembly
-
-// static
-void SecurityDeclarative::FullTrustLinkDemand(Assembly *pTargetAssembly)
-{
- CONTRACTL
- {
- THROWS;
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- PRECONDITION(CheckPointer(pTargetAssembly));
- }
- CONTRACTL_END;
-
- struct
- {
- OBJECTREF refFullTrust;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.refFullTrust = Security::CreatePermissionSet(TRUE);
- IAssemblySecurityDescriptor *pTargetASD = pTargetAssembly->GetSecurityDescriptor();
- SecurityStackWalk::LinkOrInheritanceCheck(pTargetASD,
- gc.refFullTrust,
- pTargetAssembly,
- dclLinktimeCheck);
- GCPROTECT_END();
-}
-
-// Used by interop to simulate the effect of link demands when the caller is
-// in fact script constrained by an appdomain setup by IE.
-void SecurityDeclarative::CheckLinkDemandAgainstAppDomain(MethodDesc *pMD)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- if (!pMD->RequiresLinktimeCheck())
- return;
-
- // Find the outermost (closest to caller) appdomain. This
- // represents the domain in which the unmanaged caller is
- // considered to "live" (or, at least, be constrained by).
- AppDomain *pDomain = GetThread()->GetInitialDomain();
-
- // The link check is only performed if this app domain has
- // security permissions associated with it, which will be
- // the case for all IE scripting callers that have got this
- // far because we automatically reported our managed classes
- // as "safe for scripting".
- //
- // We also can't do the check if the AppDomain isn't fully
- // setup yet, since we might not have a domain grant set.
- // This is acceptable, since the only code that should run
- // during AppDomain creation is fully trusted.
- IApplicationSecurityDescriptor *pSecDesc = pDomain->GetSecurityDescriptor();
- if (pSecDesc == NULL || pSecDesc->IsInitializationInProgress() || pSecDesc->IsDefaultAppDomain())
- return;
-
- struct _gc
- {
- OBJECTREF refGrant;
- OBJECTREF refRefused;
- OBJECTREF refClassNonCasDemands;
- OBJECTREF refClassCasDemands;
- OBJECTREF refMethodNonCasDemands;
- OBJECTREF refMethodCasDemands;
- OBJECTREF refAssembly;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
-#ifdef FEATURE_APTCA
- // Do a fulltrust check on the caller if the callee did not enable
- // AllowUntrustedCallerChecks. Pass a NULL caller assembly:
- // DoUntrustedCallerChecks needs to be able to cope with this.
- SecurityDeclarative::DoUntrustedCallerChecks(NULL, pMD, TRUE);
-#endif // FEATURE_APTCA
-
- // Fetch link demand sets from all the places in metadata where we might
- // find them (class and method). These might be split into CAS and non-CAS
- // sets as well.
- SecurityDeclarative::RetrieveLinktimeDemands(pMD,
- &gc.refClassCasDemands,
- &gc.refClassNonCasDemands,
- &gc.refMethodCasDemands,
- &gc.refMethodNonCasDemands);
-
- // Check CAS link demands.
- bool fGotGrantSet = false;
- if (gc.refClassCasDemands != NULL || gc.refMethodCasDemands != NULL)
- {
- // Get grant (and possibly denied) sets from the app
- // domain.
- gc.refGrant = pSecDesc->GetGrantedPermissionSet(NULL);
- fGotGrantSet = true;
- gc.refAssembly = pMD->GetAssembly()->GetExposedObject();
-
- if (gc.refClassCasDemands != NULL)
- SecurityStackWalk::CheckSetHelper(&gc.refClassCasDemands,
- &gc.refGrant,
- &gc.refRefused,
- pDomain,
- pMD,
- &gc.refAssembly,
- dclLinktimeCheck);
-
- if (gc.refMethodCasDemands != NULL)
- SecurityStackWalk::CheckSetHelper(&gc.refMethodCasDemands,
- &gc.refGrant,
- &gc.refRefused,
- pDomain,
- pMD,
- &gc.refAssembly,
- dclLinktimeCheck);
-
- }
-
- // Non-CAS demands are not applied against a grant
- // set, they're standalone.
- if (gc.refClassNonCasDemands != NULL)
- CheckNonCasDemand(&gc.refClassNonCasDemands);
-
- if (gc.refMethodNonCasDemands != NULL)
- CheckNonCasDemand(&gc.refMethodNonCasDemands);
-
-#ifndef FEATURE_CORECLR
- // On CORECLR, we do this from the JIT callouts if the caller is transparent: if caller is critical, no checks needed
-
- // We perform automatic linktime checks for UnmanagedCode in three cases:
- // o P/Invoke calls (shouldn't get these here, but let's be paranoid).
- // o Calls through an interface that have a suppress runtime check
- // attribute on them (these are almost certainly interop calls).
- // o Interop calls made through method impls.
- // Just walk the stack in these cases, they'll be extremely rare and the
- // perf delta isn't that huge.
- if (pMD->IsNDirect() ||
- (pMD->IsInterface() &&
- (pMD->GetMDImport()->GetCustomAttributeByName(pMD->GetMethodTable()->GetCl(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK ||
- pMD->GetMDImport()->GetCustomAttributeByName(pMD->GetMemberDef(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK) ) ||
- (pMD->IsComPlusCall() && !pMD->IsInterface()))
- SecurityStackWalk::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_UNMANAGED_CODE);
-#endif // FEATURE_CORECLR
-
- GCPROTECT_END();
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-//-----------------------------------------------------------------------------
-//
-//
-// CODE FOR PERFORMING RUN-TIME CHECKS
-//
-//
-//-----------------------------------------------------------------------------
-
-void SecurityDeclarative::EnsureAssertAllowed(MethodDesc *pMeth, MethodSecurityDescriptor *pMSD)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- PRECONDITION(CheckPointer(pMeth));
- PRECONDITION(pMSD == NULL || pMSD->GetMethod() == pMeth);
- } CONTRACTL_END;
-
- // Check if this Assembly has permission to assert
- if (pMSD == NULL || !pMSD->CanAssert()) // early out if we have an MSD and we already have checked this permission
- {
- Module* pModule = pMeth->GetModule();
- PREFIX_ASSUME_MSG(pModule != NULL, "Should be a Module pointer here");
-
- if (!Security::CanAssert(pModule))
- SecurityPolicy::ThrowSecurityException(g_SecurityPermissionClassName, SPFLAGSASSERTION);
- }
-
- // Check if the Method is allowed to assert based on transparent/critical classification
- if (!SecurityTransparent::IsAllowedToAssert(pMeth) && Security::IsTransparencyEnforcementEnabled())
- {
-#ifdef _DEBUG
- if (g_pConfig->LogTransparencyErrors())
- {
- SecurityTransparent::LogTransparencyError(pMeth, "Transparent method using a security assert");
- }
-#endif // _DEBUG
- // if assembly is transparent fail the ASSERT operations
- COMPlusThrow(kInvalidOperationException, W("InvalidOperation_AssertTransparentCode"));
- }
-
- return;
-}
-
-void SecurityDeclarative::InvokeDeclarativeActions (MethodDesc *pMeth, DeclActionInfo *pActions, MethodSecurityDescriptor *pMSD)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- OBJECTREF refPermSet = NULL;
- ARG_SLOT arg = 0;
-
- // If we get a real PermissionSet, then invoke the action.
- switch (pActions->dwDeclAction)
- {
- case DECLSEC_DEMANDS:
- SecurityStackWalk::DemandSet(SSWT_DECLARATIVE_DEMAND, pActions->pPCE, dclDemand);
- break;
-
- case DECLSEC_ASSERTIONS:
- EnsureAssertAllowed(pMeth, pMSD);
- GetThread()->IncrementAssertCount();
- break;
-
- case DECLSEC_DENIALS:
- case DECLSEC_PERMITONLY:
- GetThread()->IncrementOverridesCount();
- break;
-
- case DECLSEC_NONCAS_DEMANDS:
- refPermSet = pActions->pPCE->CreateManagedPsetObject (dclNonCasDemand);
- if (refPermSet == NULL)
- break;
- if(!((PERMISSIONSETREF)refPermSet)->CheckedForNonCas() ||((PERMISSIONSETREF)refPermSet)->ContainsNonCas())
- {
- GCPROTECT_BEGIN(refPermSet);
- MethodDescCallSite demand(METHOD__PERMISSION_SET__DEMAND_NON_CAS, &refPermSet);
-
- arg = ObjToArgSlot(refPermSet);
- demand.Call(&arg);
- GCPROTECT_END();
- }
- break;
-
- default:
- _ASSERTE(!"Unknown action requested in InvokeDeclarativeActions");
- break;
-
- } // switch
-}
-
-
-//
-// CODE FOR PERFORMING RUN-TIME CHECKS
-//
-extern LPVOID GetSecurityObjectForFrameInternal(StackCrawlMark *stackMark, INT32 create, OBJECTREF *pRefSecDesc);
-
-namespace
-{
- inline void UpdateFrameSecurityObj(DWORD dwAction, OBJECTREF *refPermSet, OBJECTREF * pSecObj)
- {
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- GetSecurityObjectForFrameInternal(NULL, true, pSecObj);
-
- FRAMESECDESCREF fsdRef = (FRAMESECDESCREF)*pSecObj;
- switch (dwAction)
- {
- // currently we require declarative security to store the data in both the fields in the FSD
- case dclAssert:
- fsdRef->SetDeclarativeAssertions(*refPermSet);
- {
- PERMISSIONSETREF psRef = (PERMISSIONSETREF)*refPermSet;
- if (psRef != NULL && psRef->IsUnrestricted())
- fsdRef->SetAssertFT(TRUE);
- }
- break;
-
- case dclDeny:
- fsdRef->SetDeclarativeDenials(*refPermSet);
- break;
-
- case dclPermitOnly:
- fsdRef->SetDeclarativeRestrictions(*refPermSet);
- break;
-
- default:
- _ASSERTE(0 && "Unreached, add code to handle if reached here...");
- break;
- }
- }
-}
-
-void SecurityDeclarative::InvokeDeclarativeStackModifiers(MethodDesc * pMeth, DeclActionInfo * pActions, OBJECTREF * pSecObj)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- OBJECTREF refPermSet = NULL;
-
- // If we get a real PermissionSet, then invoke the action.
- switch (pActions->dwDeclAction)
- {
- case DECLSEC_DEMANDS:
- case DECLSEC_NONCAS_DEMANDS:
- // Nothing to do for demands
- break;
-
- case DECLSEC_ASSERTIONS:
- refPermSet = pActions->pPCE->CreateManagedPsetObject (dclAssert);
- if (refPermSet == NULL)
- break;
- GCPROTECT_BEGIN(refPermSet);
- // Now update the frame security object
- UpdateFrameSecurityObj(dclAssert, &refPermSet, pSecObj);
- GCPROTECT_END();
- break;
-
- case DECLSEC_DENIALS:
- // Update the frame security object
- refPermSet = pActions->pPCE->CreateManagedPsetObject (dclDeny);
-
- if (refPermSet == NULL)
- break;
-
- GCPROTECT_BEGIN(refPermSet);
-
-#ifdef FEATURE_CAS_POLICY
- // Deny is only valid if we're in legacy CAS mode
- IApplicationSecurityDescriptor *pSecDesc = GetAppDomain()->GetSecurityDescriptor();
- if (!pSecDesc->IsLegacyCasPolicyEnabled())
- {
- COMPlusThrow(kNotSupportedException, W("NotSupported_CasDeny"));
- }
-#endif // FEATURE_CAS_POLICY
-
- UpdateFrameSecurityObj(dclDeny, &refPermSet, pSecObj);
-
- GCPROTECT_END();
- break;
-
- case DECLSEC_PERMITONLY:
- // Update the frame security object
- refPermSet = pActions->pPCE->CreateManagedPsetObject (dclPermitOnly);
-
- if (refPermSet == NULL)
- break;
- GCPROTECT_BEGIN(refPermSet);
- UpdateFrameSecurityObj(dclPermitOnly, &refPermSet, pSecObj);
- GCPROTECT_END();
- break;
-
-
- default:
- _ASSERTE(!"Unknown action requested in InvokeDeclarativeStackModifiers");
- break;
-
- } // switch
-}
-
-void SecurityDeclarative::DoDeclarativeActions(MethodDesc *pMeth, DeclActionInfo *pActions, LPVOID pSecObj, MethodSecurityDescriptor *pMSD)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
-#ifndef FEATURE_CAS_POLICY
- // In the CoreCLR, we don't support CAS actions outside mscorlib.
- // However, we do have to expose certain types in mscorlib due to compiler requirements
- // (c# compiler requires us to expose SecurityPermission/SecurityAction etc so that it can
- // insert a RequestMinimum for SkipVerification).
- // This means that code outside mscorlib could construct IL that has declarative security
- // in it. This is not a security issue - even if they try to create IL that asserts for
- // permissions they don't have, it's not going to work for the same reasons it didn't in the desktop.
- // However, we could have bugs like DDB 120109 where they can cause Demands to fail etc.
- // So for goodness, we're not going to do any runtime declarative work on assemblies other than mscorlib.
- if (!pMeth->GetModule()->IsSystem())
- {
- // Non-mscorlib code reached... exit
- return;
- }
-#endif //!FEATURE_CAS_POLICY
-
-
- // --------------------------------------------------------------------------- //
- // D E C L A R A T I V E S E C U R I T Y D E M A N D S //
- // --------------------------------------------------------------------------- //
- // The frame is now fully formed, arguments have been copied into place,
- // and synchronization monitors have been entered if necessary. At this
- // point, we are prepared for something to throw an exception, so we may
- // check for declarative security demands and execute them. We need a
- // well-formed frame and synchronization domain to accept security excep-
- // tions thrown by the SecurityManager. We MAY need argument values in
- // the frame so that the arguments may be finalized if security throws an
- // exception across them (unknown).
- if (pActions != NULL && pActions->dwDeclAction == DECLSEC_UNMNGD_ACCESS_DEMAND &&
- pActions->pNext == NULL)
- {
- /* We special-case the security check on single pinvoke/interop calls
- so we can avoid setting up the GCFrame */
-
- SecurityStackWalk::SpecialDemand(SSWT_DECLARATIVE_DEMAND, SECURITY_UNMANAGED_CODE);
- return;
- }
- else
- {
-#ifdef FEATURE_COMPRESSEDSTACK
- // If this is an anonymously hosted dynamic method, there aren't any direct modifiers, but if it has a compressed stack that
- // might have modifiers, mark that there are modifiers so we make sure to do a stack walk
- if(SecurityStackWalk::MethodIsAnonymouslyHostedDynamicMethodWithCSToEvaluate(pMeth))
- {
- // We don't know how many asserts or overrides might be in the compressed stack,
- // but we just need to increment the counters to ensure optimizations don't skip CS evaluation
- GetThread()->IncrementAssertCount();
- GetThread()->IncrementOverridesCount();
- }
-#endif // FEATURE_COMPRESSEDSTACK
-
- for (/**/; pActions; pActions = pActions->pNext)
- {
- if (pActions->dwDeclAction == DECLSEC_UNMNGD_ACCESS_DEMAND)
- {
- SecurityStackWalk::SpecialDemand(SSWT_DECLARATIVE_DEMAND, SECURITY_UNMANAGED_CODE);
- }
- else
- {
- InvokeDeclarativeActions(pMeth, pActions, pMSD);
- }
- }
-
- }
-}
-void SecurityDeclarative::DoDeclarativeStackModifiers(MethodDesc *pMeth, AppDomain* pAppDomain, LPVOID pSecObj)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
-#ifndef FEATURE_CAS_POLICY
- // In the CoreCLR, we don't support CAS actions outside mscorlib.
- // However, we do have to expose certain types in mscorlib due to compiler requirements
- // (c# compiler requires us to expose SecurityPermission/SecurityAction etc so that it can
- // insert a RequestMinimum for SkipVerification).
- // This means that code outside mscorlib could construct IL that has declarative security
- // in it. This is not a security issue - even if they try to create IL that asserts for
- // permissions they don't have, it's not going to work for the same reasons it didn't in the desktop.
- // However, we could have bugs like DDB 120109 where they can cause Demands to fail etc.
- // So for goodness, we're not going to do any runtime declarative work on assemblies other than mscorlib.
- if (!pMeth->GetModule()->IsSystem())
- {
- // Non-mscorlib code reached... exit
- return;
- }
-#endif //!FEATURE_CAS_POLICY
-
-
- AppDomain* pCurrentDomain = GetAppDomain();
-
- if (pCurrentDomain != pAppDomain)
- {
- ENTER_DOMAIN_PTR(pAppDomain, ADV_RUNNINGIN)
- {
- DoDeclarativeStackModifiersInternal(pMeth, pSecObj);
- }
- END_DOMAIN_TRANSITION;
- }
- else
- {
- DoDeclarativeStackModifiersInternal(pMeth, pSecObj);
- }
- }
-
-void SecurityDeclarative::DoDeclarativeStackModifiersInternal(MethodDesc *pMeth, LPVOID pSecObj)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- Object** ppSecObject = (Object**) pSecObj;
- _ASSERTE(pMeth->IsInterceptedForDeclSecurity() && !pMeth->IsInterceptedForDeclSecurityCASDemandsOnly());
-
- MethodSecurityDescriptor MDSecDesc(pMeth);
- MethodSecurityDescriptor::LookupOrCreateMethodSecurityDescriptor(&MDSecDesc);
- DeclActionInfo* pActions = MDSecDesc.GetRuntimeDeclActionInfo();
-
- OBJECTREF fsdRef = ObjectToOBJECTREF(*ppSecObject);
- GCPROTECT_BEGIN(fsdRef);
-
- for (/**/; pActions; pActions = pActions->pNext)
- {
- InvokeDeclarativeStackModifiers(pMeth, pActions, &fsdRef);
- }
- // If we had just NON-CAS demands, we'd come here but not create an FSD.
- if (fsdRef != NULL)
- {
- ((FRAMESECDESCREF)(fsdRef))->SetDeclSecComputed(TRUE);
-
- if (*ppSecObject == NULL)
- {
- // we came in with a NULL FSD and the FSD got created here...so we need to copy it back
- // If we had come in with a non-NULL FSD, that would have been updated and this (shallow/pointer) copy
- // would not be necessary
- *ppSecObject = OBJECTREFToObject(fsdRef);
- }
-}
-
- GCPROTECT_END();
-}
-
-
-void SecurityDeclarative::CheckNonCasDemand(OBJECTREF *prefDemand)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(IsProtectedByGCFrame (prefDemand));
- } CONTRACTL_END;
-
- if(((PERMISSIONSETREF)*prefDemand)->CheckedForNonCas())
- {
- if(!((PERMISSIONSETREF)*prefDemand)->ContainsNonCas())
- return;
- }
- MethodDescCallSite demand(METHOD__PERMISSION_SET__DEMAND_NON_CAS, prefDemand);
- ARG_SLOT arg = ObjToArgSlot(*prefDemand);
- demand.Call(&arg);
-}
-
-#endif // FEATURE_CAS_POLICY
#endif // CROSSGEN_COMPILE
inline BOOL FullTrustCheckForLinkOrInheritanceDemand(Assembly *pAssembly);
-#ifdef FEATURE_APTCA
- // Returns TRUE if an APTCA check is necessary
- // Callers:
- // CanAccess
- BOOL IsUntrustedCallerCheckNeeded(MethodDesc *pCalleeMD, Assembly *pCallerAssem = NULL);
-
- // Perform the APTCA check
- // Callers:
- // CanAccess
- // Security::CheckLinkDemandAgainstAppDomain
- void DoUntrustedCallerChecks(
- Assembly *pCaller, MethodDesc *pCalee,
- BOOL fFullStackWalk);
-#endif // FEATURE_APTCA
#ifndef DACCESS_COMPILE
// Calls PermissionSet.Demand
inline BOOL ClassIsVisibleOutsideItsAssembly(DWORD dwClassAttr, BOOL fIsGlobalClass);
-#ifdef FEATURE_APTCA
- // Returns an instance of a SecurityException with the message "This method doesn't allow partially trusted callers"
- // Callers:
- // DoUntrustedCallerChecks
- void DECLSPEC_NORETURN ThrowAPTCAException(Assembly *pCaller, MethodDesc *pCallee);
-#endif // FEATURE_APTCA
-#ifdef FEATURE_CAS_POLICY
- void DECLSPEC_NORETURN ThrowHPException(EApiCategories protectedCategories, EApiCategories demandedCategories);
-#endif // FEATURE_CAS_POLICY
// Add a declarative action and PermissionSet index to the linked list
void AddDeclAction(CorDeclSecurity action, PsetCacheEntry *pClassPCE, PsetCacheEntry *pMethodPCE, DeclActionInfo** ppActionList, MethodDesc *pMeth);
MODE_COOPERATIVE;
} CONTRACTL_END;
-#ifdef FEATURE_CAS_POLICY
- OBJECTREF orRet;
-
- orRet = GetManagedPsetObject();
- if (orRet != NULL) {
- return orRet;
- }
-
- if (!createEmptySet && m_fEmptyPermissionSet) {
- return NULL;
- }
-
- struct _gc {
- OBJECTREF pset;
- OBJECTREF encoding;
- OBJECTREF nonCasPset;
- OBJECTREF orNonCasPset;
- OBJECTREF orNonCasEncoding;
- } gc;
- memset(&gc, 0, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- if ( (m_pKey->m_cbPset > 0) && (m_pKey->m_pbPset[0] == LAZY_DECL_SEC_FLAG) ) {
-
- SecurityAttributes::AttrSetBlobToPermissionSets(m_pKey->m_pbPset,
- m_pKey->m_cbPset,
- &gc.pset,
- dwAction);
-
- } else {
-
- SecurityAttributes::XmlToPermissionSet(m_pKey->m_pbPset,
- m_pKey->m_cbPset,
- &gc.pset,
- &gc.encoding,
- NULL,
- 0,
- &gc.orNonCasPset,
- &gc.orNonCasEncoding);
- }
-
- StoreFirstObjectInHandle(m_handle, gc.pset);
-
- if (gc.pset == NULL)
- m_fEmptyPermissionSet = true;
-
- GCPROTECT_END();
-
- //
- // Some other thread may have won the race, and stored away a different
- // object in the handle.
- //
-
- orRet = GetManagedPsetObject();
- return orRet;
-#else
return NULL;
-#endif
}
#endif // CROSSGEN_COMPILE
//
// Returns TRUE if the given zone has the given special permission.
//
-#ifdef FEATURE_CAS_POLICY
-BOOL SecurityDescriptor::CheckQuickCache(SecurityConfig::QuickCacheEntryType all, DWORD dwZone)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(m_pAppDomain->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled());
- PRECONDITION(SecurityPolicy::s_fPolicyInitialized);
- } CONTRACTL_END;
-
- static const SecurityConfig::QuickCacheEntryType zoneTable[] =
- {
- SecurityConfig::FullTrustZoneMyComputer,
- SecurityConfig::FullTrustZoneIntranet,
- SecurityConfig::FullTrustZoneTrusted,
- SecurityConfig::FullTrustZoneInternet,
- SecurityConfig::FullTrustZoneUntrusted
- };
-
- // If an additional evidence was provided, then perform the normal
- // policy resolution. This is true for all AppDomains and also for
- // assemblies loaded with a specific additional evidence. Note that
- // for the default AppDomain, the policy resolution code paths short
- // circuits the parsing of the security XML files by granting FullTrust
- // to the default AppDomain.
-
- if (m_hAdditionalEvidence != NULL)
- return FALSE;
-
- BOOL fMachine = SecurityConfig::GetQuickCacheEntry(SecurityConfig::MachinePolicyLevel, all);
- BOOL fUser = SecurityConfig::GetQuickCacheEntry(SecurityConfig::UserPolicyLevel, all);
- BOOL fEnterprise = SecurityConfig::GetQuickCacheEntry(SecurityConfig::EnterprisePolicyLevel, all);
-
- if (fMachine && fUser && fEnterprise)
- return TRUE;
-
- // If we can't match for all, try for our zone.
- if (dwZone == 0xFFFFFFFF)
- return FALSE;
-
- fMachine = SecurityConfig::GetQuickCacheEntry(SecurityConfig::MachinePolicyLevel, zoneTable[dwZone]);
- fUser = SecurityConfig::GetQuickCacheEntry(SecurityConfig::UserPolicyLevel, zoneTable[dwZone]);
- fEnterprise = SecurityConfig::GetQuickCacheEntry(SecurityConfig::EnterprisePolicyLevel, zoneTable[dwZone]);
-
- return (fMachine && fUser && fEnterprise);
-}
-#endif // FEATURE_CAS_POLICY
#endif // DACCESS_COMPILE
-#ifdef FEATURE_CAS_POLICY
-BOOL SecurityDescriptor::IsEvidenceComputed() const
-{
- LIMITED_METHOD_CONTRACT;
- return m_fEvidenceComputed;
-}
-#endif //FEATURE_CAS_POLICY
//
// This method will return TRUE if this object is fully trusted.
}
-#ifdef FEATURE_CAS_POLICY
-void SecurityDescriptor::SetEvidence(OBJECTREF evidence)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(evidence != NULL);
- }
- CONTRACTL_END;
-
- if (evidence != NULL)
- {
- StoreObjectInLazyHandle(m_hAdditionalEvidence, evidence, m_pLoaderAllocator);
- SetEvidenceComputed();
- }
-}
-#endif // FEATURE_CAS_POLICY
#endif // !DACCESS_COMPILE
AppDomain* SecurityDescriptor::GetDomain() const
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_CAS_POLICY
-
-//---------------------------------------------------------------------------------------
-//
-// Build an evidence collection which can generate evidence about a PEFile
-//
-// Arguments:
-// pPEFile - PEFile the evidence collection will generate evidence for
-// objHostSuppliedEvidence - additional evidence to merge into the collection supplied by the host
-//
-// Return Value:
-// Evidence collection which targets this PEFile
-//
-// Notes:
-// Calls System.Security.Policy.PEFileEvidenceFactory.CreateSecurityIdentity
-//
-
-// static
-OBJECTREF PEFileSecurityDescriptor::BuildEvidence(PEFile *pPEFile, const OBJECTREF& objHostSuppliedEvidence)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pPEFile));
- }
- CONTRACTL_END;
-
- struct
- {
- SAFEHANDLE objPEFile;
- OBJECTREF objHostSuppliedEvidence;
- OBJECTREF objEvidence;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- BEGIN_SO_INTOLERANT_CODE(GetThread());
-
- gc.objPEFile = pPEFile->GetSafeHandle();
- gc.objHostSuppliedEvidence = objHostSuppliedEvidence;
-
- MethodDescCallSite createSecurityIdentity(METHOD__PEFILE_EVIDENCE_FACTORY__CREATE_SECURITY_IDENTITY);
-
- ARG_SLOT args[] =
- {
- ObjToArgSlot(gc.objPEFile),
- ObjToArgSlot(gc.objHostSuppliedEvidence)
- };
-
- gc.objEvidence = createSecurityIdentity.Call_RetOBJECTREF(args);
-
- END_SO_INTOLERANT_CODE;
- GCPROTECT_END();
-
- return gc.objEvidence;
-}
-
-#endif // FEATURE_CAS_POLICY
-
-#ifndef FEATURE_CORECLR
-BOOL PEFileSecurityDescriptor::QuickIsFullyTrusted()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
-#ifdef CROSSGEN_COMPILE
- return TRUE;
-#else
- if (!m_pAppDomain->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled())
- {
- return TRUE;
- }
- else if (m_pAppDomain->IsCompilationDomain())
- {
- return TRUE;
- }
- else
- {
- return CheckQuickCache(SecurityConfig::FullTrustAll, GetZone());
- }
-#endif
-}
-
-#ifndef CROSSGEN_COMPILE
-//---------------------------------------------------------------------------------------
-//
-// Get the evidence for this PE file
-//
-
-OBJECTREF PEFileSecurityDescriptor::GetEvidence()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(m_pAppDomain == GetAppDomain());
- INJECT_FAULT(COMPlusThrowOM());
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- // If we already have evidence, then just return that
- if (IsEvidenceComputed())
- return ObjectFromLazyHandle(m_hAdditionalEvidence, m_pLoaderAllocator);
-
- struct
- {
- OBJECTREF objHostProvidedEvidence;
- OBJECTREF objEvidence;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- BEGIN_SO_INTOLERANT_CODE(GetThread());
-
-#if CHECK_APP_DOMAIN_LEAKS
- if (g_pConfig->AppDomainLeaks())
- _ASSERTE(gc.objHostProvidedEvidence == NULL || GetAppDomain() == gc.objHostProvidedEvidence->GetAppDomain());
-#endif // CHECK_APP_DOMAIN_LEAKS
-
- gc.objHostProvidedEvidence = ObjectFromLazyHandle(m_hAdditionalEvidence, m_pLoaderAllocator);
- gc.objEvidence = PEFileSecurityDescriptor::BuildEvidence(m_pPEFile, gc.objHostProvidedEvidence);
- SetEvidence(gc.objEvidence);
-
-#if CHECK_APP_DOMAIN_LEAKS
- if (g_pConfig->AppDomainLeaks())
- _ASSERTE(gc.objEvidence == NULL || GetAppDomain() == gc.objEvidence->GetAppDomain());
-#endif // CHECK_APP_DOMAIN_LEAKS
-
- END_SO_INTOLERANT_CODE;
-
- GCPROTECT_END();
-
- return gc.objEvidence;
-}
-
-DWORD PEFileSecurityDescriptor::GetZone()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- PRECONDITION(m_pAppDomain->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled());
- }
- CONTRACTL_END;
-
- SecZone dwZone = NoZone;
- BEGIN_SO_INTOLERANT_CODE(GetThread());
-
- StackSString codebase;
- BYTE rbUniqueID[MAX_SIZE_SECURITY_ID];
- DWORD cbUniqueID = sizeof(rbUniqueID);
-
- m_pPEFile->GetSecurityIdentity(codebase, &dwZone, 0, rbUniqueID, &cbUniqueID);
- END_SO_INTOLERANT_CODE;
- return dwZone;
-}
-#endif // !CROSSGEN_COMPILE
-
-void PEFileSecurityDescriptor::Resolve()
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- if (IsResolved())
- return;
- ResolveWorker();
-}
-
-void PEFileSecurityDescriptor::ResolveWorker()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- SetGrantedPermissionSet(NULL, NULL, 0xFFFFFFFF);
-}
-
-BOOL PEFileSecurityDescriptor::AllowBindingRedirects()
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(IsResolved());
- } CONTRACTL_END;
-
- ETWOnStartup (AllowBindingRedirs_V1, AllowBindingRedirsEnd_V1);
-
- return CheckSpecialFlag(1 << SECURITY_BINDING_REDIRECTS);
-}
-#endif // FEATURE_CORECLR
#endif // !DACCESS_COMPILE
#ifndef __SECURITYDESCRIPTOR_H__
#define __SECURITYDESCRIPTOR_H__
-#include "securityconfig.h"
#include "securityattributes.h"
#include "securitypolicy.h"
class SecurityDescriptor
{
protected:
-#ifdef FEATURE_CAS_POLICY
- LOADERHANDLE m_hAdditionalEvidence; // Evidence Object
-#endif // FEATURE_CAS_POLICY
// The unmanaged DomainAssembly object
DomainAssembly *m_pAssem;
AppDomain* m_pAppDomain;
BOOL m_fSDResolved;
-#ifdef FEATURE_CAS_POLICY
- BOOL m_fEvidenceComputed;
-#endif // FEATURE_CAS_POLICY
DWORD m_dwSpecialFlags;
LoaderAllocator *m_pLoaderAllocator;
AppDomain* GetDomain() const;
BOOL CanCallUnmanagedCode() const;
-#ifdef FEATURE_CAS_POLICY
-
-#ifndef DACCESS_COMPILE
- void SetEvidence(OBJECTREF evidence);
- BOOL CheckQuickCache(SecurityConfig::QuickCacheEntryType all, DWORD dwZone);
-#endif // FEATURE_CAS_POLICY
- BOOL IsEvidenceComputed() const;
- inline void SetEvidenceComputed();
-#endif // FEATURE_CAS_POLICY
#ifndef DACCESS_COMPILE
void SetGrantedPermissionSet(OBJECTREF GrantedPermissionSet,
virtual BOOL IsResolved() const { return SecurityDescriptor::IsResolved(); }
-#ifdef FEATURE_CAS_POLICY
- virtual BOOL IsEvidenceComputed() const { return SecurityDescriptor::IsEvidenceComputed(); }
-#ifndef DACCESS_COMPILE
- virtual void SetEvidence(OBJECTREF evidence) { SecurityDescriptor::SetEvidence(evidence); }
-#endif // DACCESS_COMPILE
-#endif // FEATURE_CAS_POLICY
#ifndef DACCESS_COMPILE
virtual OBJECTREF GetGrantedPermissionSet(OBJECTREF* RefusedPermissions = NULL) { return SecurityDescriptor::GetGrantedPermissionSet(RefusedPermissions); }
#endif
};
-#ifndef FEATURE_CORECLR
-class PEFileSecurityDescriptor : public SecurityDescriptorBase<IPEFileSecurityDescriptor>
-{
-public:
- virtual BOOL AllowBindingRedirects();
- BOOL QuickIsFullyTrusted();
- virtual VOID Resolve();
-
-#ifndef DACCESS_COMPILE
- inline PEFileSecurityDescriptor(AppDomain* pDomain, PEFile *pPEFile);
-#endif
-
-#ifdef FEATURE_CAS_POLICY
- virtual OBJECTREF GetEvidence();
- DWORD GetZone();
-#endif // FEATURE_CAS_POLICY
-
-
-#ifdef FEATURE_CAS_POLICY
- static
- OBJECTREF BuildEvidence(PEFile *pPEFile, const OBJECTREF& objHostSuppliedEvidence);
-#endif // FEATURE_CAS_POLICY
-private:
- VOID ResolveWorker();
-};
-#endif // !FEATURE_CORECLR
#include "securitydescriptor.inl"
DomainAssembly *pAssembly,
PEFile* pPEFile,
LoaderAllocator *pLoaderAllocator) :
-#ifdef FEATURE_CAS_POLICY
- m_hAdditionalEvidence(NULL),
-#endif // FEATURE_CAS_POLICY
m_pAssem(pAssembly),
m_pPEFile(pPEFile),
m_pAppDomain(pAppDomain),
m_fSDResolved(FALSE),
-#ifdef FEATURE_CAS_POLICY
- m_fEvidenceComputed(FALSE),
-#endif // FEATURE_CAS_POLICY
m_dwSpecialFlags(0),
m_pLoaderAllocator(pLoaderAllocator)
#ifndef CROSSGEN_COMPILE
}
#endif // !DACCESS_COMPILE
-#ifdef FEATURE_CAS_POLICY
-inline void SecurityDescriptor::SetEvidenceComputed()
-{
- LIMITED_METHOD_CONTRACT;
- m_fEvidenceComputed = TRUE;
-}
-
-#endif // FEATURE_CAS_POLICY
// Checks for one of the special security flags such as FullTrust or UnmanagedCode
FORCEINLINE BOOL SecurityDescriptor::CheckSpecialFlag (DWORD flags) const
}
#endif // !DACCESS_COMPILE
-#ifndef FEATURE_CORECLR
-
-#ifndef DACCESS_COMPILE
-inline PEFileSecurityDescriptor::PEFileSecurityDescriptor(AppDomain* pDomain, PEFile *pPEFile) :
- SecurityDescriptorBase<IPEFileSecurityDescriptor>(pDomain, NULL,pPEFile, pDomain->GetLoaderAllocator())
-{
- LIMITED_METHOD_CONTRACT
-}
-#endif // !DACCESS_COMPILE
-
-#endif // !FEATURE_CORECLR
#endif // #define __SECURITYDESCRIPTOR_INL__
{
LIMITED_METHOD_CONTRACT;
return m_fIsDefaultAppdomain
-#ifndef FEATURE_CORECLR
- && !m_fHomogeneous
-#endif // FEATURE_CORECLR
;
}
return !m_fHomogeneous || !IsFullyTrusted();
}
-#ifdef FEATURE_APTCA
-ConditionalAptcaCache *ApplicationSecurityDescriptor::GetConditionalAptcaCache()
-{
- LIMITED_METHOD_CONTRACT;
- return m_pConditionalAptcaCache;
-}
-
-void ApplicationSecurityDescriptor::SetCanonicalConditionalAptcaList(LPCWSTR wszCanonicalConditionalAptcaList)
-{
- WRAPPER_NO_CONTRACT;
- return this->GetConditionalAptcaCache()->SetCanonicalConditionalAptcaList(wszCanonicalConditionalAptcaList);
-}
-#endif // FEATURE_APTCA
#endif // !DACCESS_COMPILE
// exists on the AppDomain. (In the managed world: AppDomain._SecurityIdentity != null)
BOOL m_fHomogeneous; // This AppDomain has an ApplicationTrust
BOOL m_fRuntimeSuppliedHomogenousGrantSet; // This AppDomain is homogenous only because the v4 CLR defaults to creating homogenous domains, and would not have been homogenous in v2
-#ifdef FEATURE_CAS_POLICY
- BOOL m_fLegacyCasPolicy; // This AppDomain is using legacy CAS policy
-#endif // FEATURE_CAS_POLICY
DWORD m_dwHostSecurityManagerFlags; // Flags indicating what decisions the host wants to participate in.
BOOL m_fContainsAnyRefusedPermissions;
BOOL m_fPreResolutionFullTrust; // Was the domain pre-resolved to be full trust
BOOL m_fPreResolutionHomogeneous; // Was the domain pre-resolved to be homogenous
-#ifdef FEATURE_APTCA
- ConditionalAptcaCache* m_pConditionalAptcaCache; // Cache of known conditional APTCA assemblies in this domain
-#endif // FEATURE_APTCA
#ifndef DACCESS_COMPILE
public:
//--------------------
// Destructor
//--------------------
-#ifdef FEATURE_APTCA // The destructor only deletes the ConditionalAptcaCache
- inline ~ApplicationSecurityDescriptor();
-#endif // FEATURE_APTCA
public:
// Indicates whether the initialization phase is in progress.
inline void SetHomogeneousFlag(BOOL fRuntimeSuppliedHomogenousGrantSet);
virtual BOOL IsHomogeneous() const;
-#ifdef FEATURE_CAS_POLICY
- virtual BOOL IsLegacyCasPolicyEnabled();
- virtual void SetLegacyCasPolicyEnabled();
-#endif // FEATURE_CAS_POLICY
virtual BOOL ContainsAnyRefusedPermissions();
// Should the HSM be consulted for security decisions in this AppDomain.
virtual BOOL CallHostSecurityManager();
-#ifdef FEATURE_CAS_POLICY
- // Does the domain's HSM need to be consulted for assemblies loaded into the domain
- inline BOOL CallHostSecurityManagerForAssemblies();
-#endif // FEATURE_CAS_POLICY
// Initialize the PLS on the AppDomain.
void InitializePLS();
inline BOOL CheckDomainWideSpecialFlag(DWORD flags) const;
virtual DWORD GetDomainWideSpecialFlag() const;
-#ifdef FEATURE_CAS_POLICY
- virtual OBJECTREF GetEvidence();
- DWORD GetZone();
-
- virtual BOOL AllowsLoadsFromRemoteSources();
-#endif // FEATURE_CAS_POLICY
virtual BOOL DomainMayContainPartialTrustCode();
BOOL QuickIsFullyTrusted();
-#ifdef FEATURE_APTCA
- virtual ConditionalAptcaCache *GetConditionalAptcaCache();
- virtual void SetCanonicalConditionalAptcaList(LPCWSTR wszCanonicalConditionalAptcaList);
-#endif // FEATURE_APTCA
#endif // #ifndef DACCESS_COMPILE
};
m_fIsDefaultAppdomainEvidence(FALSE),
m_fHomogeneous(FALSE),
m_fRuntimeSuppliedHomogenousGrantSet(FALSE),
-#ifdef FEATURE_CAS_POLICY
- m_fLegacyCasPolicy(Security::IsProcessWideLegacyCasPolicyEnabled()),
-#endif // FEATURE_CAS_POLICY
m_dwHostSecurityManagerFlags(HOST_NONE),
m_fContainsAnyRefusedPermissions(FALSE),
m_fIsPreResolved(FALSE),
m_fPreResolutionFullTrust(FALSE),
m_fPreResolutionHomogeneous(FALSE)
-#ifdef FEATURE_APTCA
- ,m_pConditionalAptcaCache(new ConditionalAptcaCache(pAppDomain))
-#endif // FEATURE_APTCA
{
CONTRACTL
{
return;
}
-#ifdef FEATURE_APTCA
-inline ApplicationSecurityDescriptor::~ApplicationSecurityDescriptor()
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_ANY;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- delete m_pConditionalAptcaCache;
-}
-#endif // FEATURE_APTCA
inline void ApplicationSecurityDescriptor::ResetInitializationInProgress()
{
m_fRuntimeSuppliedHomogenousGrantSet = fRuntimeSuppliedHomogenousGrantSet;
}
-#ifdef FEATURE_CAS_POLICY
-
-// Does the domain's HSM need to be consulted for assemblies loaded into the domain
-inline BOOL ApplicationSecurityDescriptor::CallHostSecurityManagerForAssemblies()
-{
- LIMITED_METHOD_CONTRACT;
-
- // We always need to call the HSM if it wants to specify the assembly's grant set
- if (m_dwHostSecurityManagerFlags & HOST_RESOLVE_POLICY)
- {
- return TRUE;
- }
-
- // In legacy CAS mode, we also need to call the HSM if it wants to supply evidence or if we have an
- // AppDomain policy level
- if (IsLegacyCasPolicyEnabled())
- {
- if ((m_dwHostSecurityManagerFlags & HOST_ASM_EVIDENCE) ||
- (m_dwHostSecurityManagerFlags & HOST_POLICY_LEVEL))
- {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-#endif // FEATURE_CAS_POLICY
#endif // #ifndef DACCESS_COMPILE
m_dwNumPassedDemands(0),
m_pSignature(NULL),
m_pSharedSecDesc(NULL),
-#ifdef FEATURE_CAS_POLICY
- m_hRequiredPermissionSet(NULL),
- m_hOptionalPermissionSet(NULL),
- m_hDeniedPermissionSet(NULL),
- m_fAdditionalEvidence(FALSE),
- m_fIsSignatureLoaded(FALSE),
- m_fAssemblyRequestsComputed(FALSE),
-#endif
m_fMicrosoftPlatform(FALSE),
m_fAllowSkipVerificationInFullTrust(TRUE)
{
if (IsSystem())
return TRUE;
-#ifdef FEATURE_CAS_POLICY
-
- // NGEN is always done in full trust
- if (m_pAppDomain->IsCompilationDomain())
- {
- return TRUE;
- }
-
- // If the assembly is in the GAC then it gets FullTrust.
- if (m_pAssem->GetFile()->IsSourceGAC())
- return TRUE;
-
- // quickly detect if we've got a request refused or a request optional.
- if (m_pAppDomain->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled())
- {
- ReleaseHolder<IMDInternalImport> pImport(m_pAssem->GetFile()->GetMDImportWithRef());
- if (SecurityAttributes::RestrictiveRequestsInAssembly(pImport))
- return FALSE;
- }
-
- // Check if we need to call the HostSecurityManager.
- ApplicationSecurityDescriptor* pAppSecDesc = static_cast<ApplicationSecurityDescriptor*>(m_pAppDomain->GetSecurityDescriptor());
- if (pAppSecDesc->CallHostSecurityManagerForAssemblies())
- return FALSE;
-
- // - If the AppDomain is homogeneous, we currently simply detect the FT case
- // - Not having CAS on implies full trust. We can get here if we're still in the process of setting up
- // the AppDomain and the CLR hasn't yet setup the homogenous flag.
- // - Otherwise, check the quick cache
- if (pAppSecDesc->IsHomogeneous())
- {
- return m_pAppDomain->GetSecurityDescriptor()->IsFullyTrusted();
- }
- else if (!m_pAppDomain->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled())
- {
- return TRUE;
- }
- else if (CheckQuickCache(SecurityConfig::FullTrustAll, GetZone()))
- {
- return TRUE;
- }
-#endif
// See if we've already determined that the assembly is FT
// in another AppDomain, in case this is a shared assembly.
Resolve();
}
-#ifdef FEATURE_CAS_POLICY
-//-----------------------------------------------------------------------------------------------------------
-//
-// Use the evidence already generated for this assembly's PEFile as the evidence for the assembly
-//
-// Arguments:
-// pPEFileSecDesc - PEFile security descriptor contining the already generated evidence
-//
-void AssemblySecurityDescriptor::SetEvidenceFromPEFile(IPEFileSecurityDescriptor *pPEFileSecDesc)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pPEFileSecDesc));
- PRECONDITION(GetPEFile()->Equals(static_cast<PEFileSecurityDescriptor*>(pPEFileSecDesc)->GetPEFile()));
- }
- CONTRACTL_END;
-
- // If we couldn't determine the assembly was fully trusted without first generating evidence for it,
- // then we cannot reuse the PEFile's evidence. In that case we'll just use what we've generated for the
- // assembly, and discard the PEFile's version.
- if (!IsEvidenceComputed())
- {
- struct
- {
- OBJECTREF objPEFileEvidence;
- OBJECTREF objEvidence;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.objPEFileEvidence = pPEFileSecDesc->GetEvidence();
- gc.objEvidence = UpgradePEFileEvidenceToAssemblyEvidence(gc.objPEFileEvidence);
- SetEvidence(gc.objEvidence);
-
- GCPROTECT_END();
- }
-}
-
-//---------------------------------------------------------------------------------------
-//
-// Get the evidence collection for this Assembly
-//
-//
-OBJECTREF AssemblySecurityDescriptor::GetEvidence()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(m_pAppDomain == GetAppDomain());
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- // If we already have evidence, then just return that
- if (IsEvidenceComputed())
- return ObjectFromLazyHandle(m_hAdditionalEvidence, m_pLoaderAllocator);
-
- struct
- {
- OBJECTREF objHostProvidedEvidence;
- OBJECTREF objPEFileEvidence;
- OBJECTREF objEvidence;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- BEGIN_SO_INTOLERANT_CODE(GetThread());
-
- gc.objHostProvidedEvidence = ObjectFromLazyHandle(m_hAdditionalEvidence, m_pLoaderAllocator);
-
-#if CHECK_APP_DOMAIN_LEAKS
- if (g_pConfig->AppDomainLeaks())
- {
- _ASSERTE(gc.objPEFileEvidence == NULL || GetAppDomain() == gc.objPEFileEvidence->GetAppDomain());
- _ASSERTE(gc.objHostProvidedEvidence == NULL || GetAppDomain() == gc.objHostProvidedEvidence->GetAppDomain());
- }
-#endif // CHECK_APP_DOMAIN_LEAKS
-
- //
- // First get an evidence collection which targets our PEFile, then upgrade it to use this assembly as a
- // target. We create a new Evidence for the PEFile here, which means that any evidence that PEFile may
- // have already had is not used in this upgrade. If an existing PEFileSecurityDescriptor exists for the
- // PEFile, then that should be upgraded directly, rather than going through this code path.
- //
-
- gc.objPEFileEvidence = PEFileSecurityDescriptor::BuildEvidence(m_pPEFile, gc.objHostProvidedEvidence);
- gc.objEvidence = UpgradePEFileEvidenceToAssemblyEvidence(gc.objPEFileEvidence);
- SetEvidence(gc.objEvidence);
-
-#if CHECK_APP_DOMAIN_LEAKS
- if (g_pConfig->AppDomainLeaks())
- _ASSERTE(gc.objEvidence == NULL || GetAppDomain() == gc.objEvidence->GetAppDomain());
-#endif // CHECK_APP_DOMAIN_LEAKS
-
- END_SO_INTOLERANT_CODE;
-
- GCPROTECT_END();
-
- return gc.objEvidence;
-}
-#endif // FEATURE_CAS_POLICY
#endif // !DACCESS_COMPILE
BOOL AssemblySecurityDescriptor::IsSystem()
pSharedSecDesc->Resolve(this);
}
-#ifdef FEATURE_CAS_POLICY
-// This routine is called when we have determined that it that there is no SECURITY reason
-// to verify an image, but we may want to do so anyway to insure that 3rd parties don't
-// accidentally ship delay signed dlls because the application happens to be full trust.
-//
-static bool DontNeedToFlagAccidentalDelaySigning(PEAssembly* assem)
-{
- WRAPPER_NO_CONTRACT;
-
- // If the file has a native image, then either it is strongly named and can be considered
- // fully signed (see additional comments in code:PEAssembly::IsFullySigned), or it is not
- // strong named and thus can't be delay signed. Either way no check is needed.
- // If the file fully signed, then people did not accidentally forget, so no check is needed
- if (assem->HasNativeImage() || assem->IsFullySigned())
- return true;
-
- // If mscorlib itself is not signed, this is not an offical CLR, you don't need to
- // to do the checking in this case either because 3rd parties should not be running this way.
- // This is useful because otherwise when we run perf runs on normal CLR lab builds we don't
- // measure the performance that we get for a offical runtime (since official runtimes will
- // be signed).
- PEAssembly* mscorlib = SystemDomain::SystemFile();
- if (!mscorlib->HasNativeImage())
- return false;
- if ((mscorlib->GetLoadedNative()->GetNativeHeader()->COR20Flags & COMIMAGE_FLAGS_STRONGNAMESIGNED) == 0)
- return true;
-
- return false;
-}
-#endif // FEATURE_CAS_POLICY
void AssemblySecurityDescriptor::ResolveWorker()
{
__dcimf.Pop();
}
-#ifdef FEATURE_CAS_POLICY
-DWORD AssemblySecurityDescriptor::GetZone()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- PRECONDITION(m_pAppDomain->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled());
- } CONTRACTL_END;
-
- StackSString codebase;
- SecZone dwZone = NoZone;
- BYTE rbUniqueID[MAX_SIZE_SECURITY_ID];
- DWORD cbUniqueID = sizeof(rbUniqueID);
-
- m_pAssem->GetSecurityIdentity(codebase, &dwZone, 0, rbUniqueID, &cbUniqueID);
- return dwZone;
-}
-#endif // FEATURE_CAS_POLICY
Assembly* AssemblySecurityDescriptor::GetAssembly()
{
}
-#ifdef FEATURE_CAS_POLICY
-//-----------------------------------------------------------------------------------------------------------
-//
-// Upgrade the evidence used for resolving a PEFile to be targeted at the Assembly the PEFile represents
-//
-// Arguments:
-// objPEFileEvidence -
-//
-// Notes:
-// During CLR startup we may need to resolve policy against a PEFile before we have the associated
-// Assembly. Once we have the Assembly we don't want to recompute potenially expensive evidence, so this
-// method can be used to upgrade the evidence who's target was the PEFile to target the assembly instead.
-//
-// Will call into System.Reflection.Assembly.UpgradeSecurityIdentity
-//
-OBJECTREF AssemblySecurityDescriptor::UpgradePEFileEvidenceToAssemblyEvidence(const OBJECTREF& objPEFileEvidence)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(objPEFileEvidence != NULL);
- }
- CONTRACTL_END;
-
- struct
- {
- OBJECTREF objAssembly;
- OBJECTREF objEvidence;
- OBJECTREF objUpgradedEvidence;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.objAssembly = m_pAssem->GetExposedAssemblyObject();
- gc.objEvidence = objPEFileEvidence;
-
- MethodDescCallSite upgradeSecurityIdentity(METHOD__ASSEMBLY_EVIDENCE_FACTORY__UPGRADE_SECURITY_IDENTITY);
-
- ARG_SLOT args[] =
- {
- ObjToArgSlot(gc.objEvidence),
- ObjToArgSlot(gc.objAssembly)
- };
-
- gc.objUpgradedEvidence = upgradeSecurityIdentity.Call_RetOBJECTREF(args);
-
- GCPROTECT_END();
-
- return gc.objUpgradedEvidence;
-}
-
-HRESULT AssemblySecurityDescriptor::LoadSignature(COR_TRUST **ppSignature)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- } CONTRACTL_END;
-
- if (IsSignatureLoaded())
- {
- if (ppSignature)
- {
- *ppSignature = m_pSignature;
- }
-
- return S_OK;
- }
-
- GCX_PREEMP();
- m_pSignature = m_pAssem->GetFile()->GetAuthenticodeSignature();
-
- SetSignatureLoaded();
-
- if (ppSignature)
- {
- *ppSignature = m_pSignature;
- }
-
- return S_OK;
-}
-
-void AssemblySecurityDescriptor::SetAdditionalEvidence(OBJECTREF evidence)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- StoreObjectInLazyHandle(m_hAdditionalEvidence, evidence, m_pLoaderAllocator);
- m_fAdditionalEvidence = TRUE;
-}
-
-BOOL AssemblySecurityDescriptor::HasAdditionalEvidence()
-{
- LIMITED_METHOD_CONTRACT;
- return m_fAdditionalEvidence;
-}
-
-OBJECTREF AssemblySecurityDescriptor::GetAdditionalEvidence()
-{
- WRAPPER_NO_CONTRACT;
- return ObjectFromLazyHandle(m_hAdditionalEvidence, m_pLoaderAllocator);
-}
-#endif // FEATURE_CAS_POLICY
-
-#ifndef FEATURE_CORECLR
-BOOL AssemblySecurityDescriptor::AllowApplicationSpecifiedAppDomainManager()
-{
- WRAPPER_NO_CONTRACT;
-
- // Only fully trusted assemblies are allowed to specify their AppDomainManager in a config file
- return this->IsFullyTrusted();
-}
-#endif // FEATURE_CORECLR
// Check to make sure that security will allow this assembly to load. Throw an exception if the assembly
// should be forbidden from loading for security related purposes
COR_TRUST *m_pSignature; // Contains the publisher, requested permission
SharedSecurityDescriptor *m_pSharedSecDesc; // Shared state for assemblies loaded into multiple appdomains
-#ifdef FEATURE_CAS_POLICY
- LOADERHANDLE m_hRequiredPermissionSet; // Required Requested Permissions
- LOADERHANDLE m_hOptionalPermissionSet; // Optional Requested Permissions
- LOADERHANDLE m_hDeniedPermissionSet; // Denied Permissions
-
- BOOL m_fAdditionalEvidence;
- BOOL m_fIsSignatureLoaded;
- BOOL m_fAssemblyRequestsComputed;
-#endif // FEATURE_CAS_POLICY
BOOL m_fMicrosoftPlatform;
BOOL m_fAllowSkipVerificationInFullTrust;
virtual void PropagatePermissionSet(OBJECTREF GrantedPermissionSet, OBJECTREF DeniedPermissionSet, DWORD dwSpecialFlags);
#endif // !DACCESS_COMPILE
-#ifdef FEATURE_CAS_POLICY
- virtual HRESULT LoadSignature(COR_TRUST **ppSignature = NULL);
- virtual OBJECTREF GetEvidence();
- DWORD GetZone();
-
- OBJECTREF GetRequestedPermissionSet(OBJECTREF *pOptionalPermissionSet, OBJECTREF *pDeniedPermissionSet);
-
-#ifndef DACCESS_COMPILE
- virtual void SetAdditionalEvidence(OBJECTREF evidence);
- virtual BOOL HasAdditionalEvidence();
- virtual OBJECTREF GetAdditionalEvidence();
- virtual void SetEvidenceFromPEFile(IPEFileSecurityDescriptor *pPEFileSecDesc);
-#endif // !DACCESS_COMPILE
-#endif // FEATURE_CAS_POLICY
-#ifndef FEATURE_CORECLR
- virtual BOOL AllowApplicationSpecifiedAppDomainManager();
-#endif // !FEATURE_CORECLR
virtual void CheckAllowAssemblyLoad();
void ResolveWorker();
-#ifdef FEATURE_CAS_POLICY
- inline BOOL IsAssemblyRequestsComputed();
- inline BOOL IsSignatureLoaded();
- inline void SetSignatureLoaded();
-#endif
-#ifdef FEATURE_APTCA
- // If you think you need to call this method, you're probably wrong. We shouldn't be making any
- // security enforcement decisions based upon this result -- it's strictly for ensuring that we load
- // conditional APTCA assemblies correctly.
- inline BOOL IsConditionalAptca();
-#endif // FEATURE_APTCA
#endif // #ifndef DACCESS_COMPILE
};
m_arrPassedLinktimeDemands[m_dwNumPassedDemands++] = pCasDemands;
}
-#ifdef FEATURE_CAS_POLICY
-inline BOOL AssemblySecurityDescriptor::IsAssemblyRequestsComputed()
-{
- LIMITED_METHOD_CONTRACT;
- return m_fAssemblyRequestsComputed;
-}
-
-inline BOOL AssemblySecurityDescriptor::IsSignatureLoaded()
-{
- LIMITED_METHOD_CONTRACT;
- return m_fIsSignatureLoaded;
-}
-
-inline void AssemblySecurityDescriptor::SetSignatureLoaded()
-{
- LIMITED_METHOD_CONTRACT;
- m_fIsSignatureLoaded = TRUE;
-}
-
-#endif // FEATURE_CAS_POLICY
-
-#ifdef FEATURE_APTCA
-
-inline BOOL AssemblySecurityDescriptor::IsConditionalAptca()
-{
- WRAPPER_NO_CONTRACT;
- ModuleSecurityDescriptor *pMSD = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(m_pAssem->GetAssembly());
- return (pMSD->GetTokenFlags() & TokenSecurityDescriptorFlags_ConditionalAPTCA) == TokenSecurityDescriptorFlags_ConditionalAPTCA;
-}
-
-#endif // FEATURE_APTCA
#endif // !DACCESS_COMPILE
return;
}
-#ifndef FEATURE_CORECLR
- FieldSecurityDescriptorTransparencyEtwEvents etw(this);
-#endif // !FEATURE_CORECLR
#ifdef _DEBUG
// If we've setup a breakpoint when we compute the transparency of this field, then stop in the debugger
}
CONTRACTL_END;
-#ifndef FEATURE_CORECLR
- MethodSecurityDescriptorTransparencyEtwEvents etw(this);
-#endif // !FEATURE_CORECLR
MethodTable* pMT = m_pMD->GetMethodTable();
}
}
-#ifndef FEATURE_CORECLR
- // Check CAS Inheritance
-
- // Early out if we're fully trusted
- if (SecurityDeclarative::FullTrustCheckForLinkOrInheritanceDemand(pChildMD->GetAssembly()))
- {
- return;
- }
-
- if (HasInheritanceDeclarativeSecurity())
- {
-#ifdef CROSSGEN_COMPILE
- // NGen is always full trust. This path should be unreachable.
- CrossGenNotSupported("HasInheritanceDeclarativeSecurity()");
-#else // CROSSGEN_COMPILE
- GCX_COOP();
-
- OBJECTREF refCasDemands = NULL;
- PsetCacheEntry* pCasDemands = NULL;
-
- HRESULT hr = GetDeclaredPermissionsWithCache(dclInheritanceCheck, &refCasDemands, &pCasDemands);
- if (refCasDemands != NULL)
- {
- _ASSERTE(pCasDemands != NULL);
-
- // See if inheritor's assembly has passed this demand before
- AssemblySecurityDescriptor *pInheritorAssem = static_cast<AssemblySecurityDescriptor*>(pChildMD->GetAssembly()->GetSecurityDescriptor());
- BOOL fSkipCheck = pInheritorAssem->AlreadyPassedDemand(pCasDemands);
-
- if (!fSkipCheck)
- {
- GCPROTECT_BEGIN(refCasDemands);
-
- // Perform the check (it's really just a LinkDemand)
- SecurityStackWalk::LinkOrInheritanceCheck(pChildMD->GetAssembly()->GetSecurityDescriptor(), refCasDemands, pChildMD->GetAssembly(), dclInheritanceCheck);
-
- // Demand passed. Add it to the Inheritor's assembly's list of passed demands
- pInheritorAssem->TryCachePassedDemand(pCasDemands);
-
- GCPROTECT_END();
- }
- }
-
- // @todo -- non cas shouldn't be used for inheritance demands...
-
- // Check non-CAS Inheritance
- OBJECTREF refNonCasDemands = NULL;
- hr = GetDeclaredPermissionsWithCache( dclNonCasInheritance, &refNonCasDemands, NULL);
- if (refNonCasDemands != NULL)
- {
- _ASSERTE(((PERMISSIONSETREF)refNonCasDemands)->CheckedForNonCas() && "Declarative permissions should have been checked for nonCAS in PermissionSet.CreateSerialized");
- if (((PERMISSIONSETREF)refNonCasDemands)->ContainsNonCas())
- {
- GCPROTECT_BEGIN(refNonCasDemands);
-
- // Perform the check
- MethodDescCallSite demand(METHOD__PERMISSION_SET__DEMAND_NON_CAS, &refNonCasDemands);
- ARG_SLOT arg = ObjToArgSlot(refNonCasDemands);
- demand.Call(&arg);
-
- GCPROTECT_END();
- }
- }
-#endif // CROSSGEN_COMPILE
- }
-#endif // FEATURE_CORECLR
}
MethodSecurityDescriptor::MethodImplementationIterator::MethodImplementationIterator(MethodDesc *pMD)
return pTypeSecurityDesc;
}
-#if !defined(CROSSGEN_COMPILE) && defined(FEATURE_CAS_POLICY)
-HRESULT TokenDeclActionInfo::GetDeclaredPermissionsWithCache(
- IN CorDeclSecurity action,
- OUT OBJECTREF *pDeclaredPermissions,
- OUT PsetCacheEntry **pPCE)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
- HRESULT hr = S_OK;
- DWORD dwActionFlag = DclToFlag((CorDeclSecurity)action);
-
- PsetCacheEntry *ptempPCE=NULL;
- TokenDeclActionInfo* pCurrentAction = this;
- for (;
- pCurrentAction;
- pCurrentAction = pCurrentAction->pNext)
- {
- if (pCurrentAction->dwDeclAction == dwActionFlag)
- {
- ptempPCE = pCurrentAction->pPCE;
- break;
- }
- }
- if (pDeclaredPermissions && pCurrentAction)
- {
- *pDeclaredPermissions = ptempPCE->CreateManagedPsetObject (action);
- }
- if (pPCE && pCurrentAction)
- {
- *pPCE = ptempPCE;
- }
-
- return hr;
-}
-
-OBJECTREF TokenDeclActionInfo::GetLinktimePermissions(OBJECTREF *prefNonCasDemands)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- OBJECTREF refCasDemands = NULL;
- GCPROTECT_BEGIN(refCasDemands);
-
- GetDeclaredPermissionsWithCache(
- dclLinktimeCheck,
- &refCasDemands, NULL);
-
- TokenDeclActionInfo::GetDeclaredPermissionsWithCache(
- dclNonCasLinkDemand,
- prefNonCasDemands, NULL);
-
- GCPROTECT_END();
- return refCasDemands;
-}
-
-void TokenDeclActionInfo::InvokeLinktimeChecks(Assembly* pCaller)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- INJECT_FAULT(COMPlusThrowOM(););
- PRECONDITION(CheckPointer(pCaller));
- }
- CONTRACTL_END;
-
-#ifdef FEATURE_MULTICOREJIT
-
- // Reset the flag to allow managed code to be called in multicore JIT background thread from this routine
- ThreadStateNCStackHolder holder(-1, Thread::TSNC_CallingManagedCodeDisabled);
-
-#endif
-
- struct gc
- {
- OBJECTREF refNonCasDemands;
- OBJECTREF refCasDemands;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- // CAS LinkDemands
- GetDeclaredPermissionsWithCache(dclLinktimeCheck,
- &gc.refCasDemands,
- NULL);
-
- if (gc.refCasDemands != NULL)
- {
- SecurityStackWalk::LinkOrInheritanceCheck(pCaller->GetSecurityDescriptor(), gc.refCasDemands, pCaller, dclLinktimeCheck);
- }
-
- // NON CAS LinkDEMANDS (we shouldn't support this).
- GetDeclaredPermissionsWithCache(dclNonCasLinkDemand,
- &gc.refNonCasDemands,
- NULL);
-
- GCPROTECT_END();
-}
-#endif // !CROSSGEN_COMPILE && FEATURE_CAS_POLICY
void TypeSecurityDescriptor::ComputeCriticalTransparentInfo()
{
}
CONTRACTL_END;
-#ifndef FEATURE_CORECLR
- TypeSecurityDescriptorTransparencyEtwEvents etw(this);
-#endif // !FEATURE_CORECLR
#ifdef _DEBUG
// If we've setup a breakpoint when we compute the transparency of this type, then stop in the debugger now
// Update the cached values in the EE Class.
g_IBCLogger.LogEEClassCOWTableAccess(m_pMT);
pClass->SetCriticalTransparentInfo(
-#ifndef FEATURE_CORECLR
- typeFlags & (TypeSecurityDescriptorFlags_IsCritical | TypeSecurityDescriptorFlags_IsAllCritical),
-#endif // FEATURE_CORECLR
typeFlags & TypeSecurityDescriptorFlags_IsTreatAsSafe,
typeFlags & TypeSecurityDescriptorFlags_IsAllTransparent,
typeFlags & TypeSecurityDescriptorFlags_IsAllCritical);
}
}
-#ifndef FEATURE_CORECLR
- // Fast path check
- if (SecurityDeclarative::FullTrustCheckForLinkOrInheritanceDemand(pChildMT->GetAssembly()))
- {
- return;
- }
-
- if (HasInheritanceDeclarativeSecurity())
- {
-#ifdef CROSSGEN_COMPILE
- // NGen is always full trust. This path should be unreachable.
- CrossGenNotSupported("HasInheritanceDeclarativeSecurity()");
-#else // CROSSGEN_COMPILE
- GCX_COOP();
-
- // If we have a class that requires inheritance checks,
- // then we require a thread to perform the checks.
- // We won't have a thread when some of the system classes
- // are preloaded, so make sure that none of them have
- // inheritance checks.
- _ASSERTE(GetThread() != NULL);
-
- struct
- {
- OBJECTREF refCasDemands;
- OBJECTREF refNonCasDemands;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- EEClass *pClass = m_pMT->GetClass();
- if (pClass->RequiresCasInheritanceCheck())
- {
- GetDeclaredPermissionsWithCache(dclInheritanceCheck, &gc.refCasDemands, NULL);
- }
-
- if (pClass->RequiresNonCasInheritanceCheck())
- {
- GetDeclaredPermissionsWithCache(dclNonCasInheritance, &gc.refNonCasDemands, NULL);
- }
-
- if (gc.refCasDemands != NULL)
- {
- SecurityStackWalk::LinkOrInheritanceCheck(pChildMT->GetAssembly()->GetSecurityDescriptor(),
- gc.refCasDemands,
- pChildMT->GetAssembly(),
- dclInheritanceCheck);
- }
-
- if (gc.refNonCasDemands != NULL)
- {
- _ASSERTE(((PERMISSIONSETREF)gc.refNonCasDemands)->CheckedForNonCas() && "Declarative permissions should have been checked for nonCAS in PermissionSet.CreateSerialized");
- if(((PERMISSIONSETREF)gc.refNonCasDemands)->ContainsNonCas())
- {
- MethodDescCallSite demand(METHOD__PERMISSION_SET__DEMAND_NON_CAS, &gc.refNonCasDemands);
-
- ARG_SLOT arg = ObjToArgSlot(gc.refNonCasDemands);
- demand.Call(&arg);
- }
- }
-
- GCPROTECT_END();
-#endif // CROSSGEN_COMPILE
- }
-#endif // FEATURE_CORECLR
}
// Module security descriptor contains static security information about the module
return;
}
-#ifndef FEATURE_CORECLR
- ModuleSecurityDescriptorTransparencyEtwEvents etw(this);
-#endif // !FEATURE_CORECLR
// Read the security attributes from the assembly
Assembly *pAssembly = m_pModule->GetAssembly();
// choosing.
TokenSecurityDescriptorFlags tokenFlags = GetTokenFlags();
-#ifdef FEATURE_APTCA
- // We need to post-process the APTCA bits on the token security descriptor to handle:
- // 1. Conditional APTCA assemblies, which should appear as either APTCA-enabled or APTCA-disabled
- // 2. APTCA killbitted assemblies, which should appear as APTCA-disabled
- tokenFlags = ProcessAssemblyAptcaFlags(pAssembly->GetDomainAssembly(), tokenFlags);
-#endif // FEATURE_APTCA
-#ifndef FEATURE_CORECLR
- // Make sure we understand the security rule set being asked for
- if (GetSecurityRuleSet() < SecurityRuleSet_Min || GetSecurityRuleSet() > SecurityRuleSet_Max)
- {
- // Unknown rule set - fail to load this module
- SString strAssemblyName;
- pAssembly->GetDisplayName(strAssemblyName);
- COMPlusThrow(kFileLoadException, IDS_E_UNKNOWN_SECURITY_RULESET, strAssemblyName.GetUnicode());
- }
-
-#endif // !FEATURE_CORECLR
// Get a transparency behavior object for the assembly.
const SecurityTransparencyBehavior *pTransparencyBehavior =
}
}
-#ifdef FEATURE_APTCA
- // If the security model implies that unsigned assemblies are APTCA, then check to see if we're unsigned
- // and set the APTCA bit.
- if (pTransparencyBehavior->DoesUnsignedImplyAPTCA() && !pAssembly->IsStrongNamed())
- {
- moduleFlags |= ModuleSecurityDescriptorFlags_IsAPTCA;
- }
-#endif // FEATURE_APTCA
#ifdef _DEBUG
// If we're being forced to generate native code for this assembly which can be used in a partial trust
_ASSERTE(m_flags == moduleFlags);
}
-#ifndef FEATURE_CORECLR
-
-// Determine if this assembly was build against a version of the runtime that only supported legacy transparency
-BOOL ModuleSecurityDescriptor::AssemblyVersionRequiresLegacyTransparency()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- SO_INTOLERANT;
- }
- CONTRACTL_END;
-
- BOOL fIsLegacyAssembly = FALSE;
-
- // Check the manifest version number to see if we're a v1 or v2 assembly. We specifically check for the
- // manifest version to come back as a string that starts with either v1 or v2; if we get anything
- // unexpected, we'll just use the default transparency implementation
- LPCSTR szVersion = NULL;
- IMDInternalImport *pmdImport = m_pModule->GetAssembly()->GetManifestImport();
- if (SUCCEEDED(pmdImport->GetVersionString(&szVersion)))
- {
- if (szVersion != NULL && strlen(szVersion) > 2)
- {
- fIsLegacyAssembly = szVersion[0] == 'v' &&
- (szVersion[1] == '1' || szVersion[1] == '2');
- }
- }
-
- return fIsLegacyAssembly;
-}
-
-#endif // !FEATURE_CORECLR
ModuleSecurityDescriptor* ModuleSecurityDescriptor::GetModuleSecurityDescriptor(Assembly *pAssembly)
{
{
flags |= TokenSecurityDescriptorFlags_Critical;
-#ifndef FEATURE_CORECLR
- // Check the SecurityCriticalScope parameter
- const BYTE *pbAttributeBlob;
- ULONG cbAttributeBlob;
-
- if (FAILED(pmdImport->GetCustomAttributeAsBlob(
- currentAttribute,
- reinterpret_cast<const void **>(&pbAttributeBlob),
- &cbAttributeBlob)))
- {
- continue;
- }
- CustomAttributeParser cap(pbAttributeBlob, cbAttributeBlob);
- if (SUCCEEDED(cap.SkipProlog()))
- {
- UINT32 dwCriticalFlags;
- if (SUCCEEDED(cap.GetU4(&dwCriticalFlags)))
- {
- if (dwCriticalFlags == SecurityCriticalFlags_All)
- {
- flags |= TokenSecurityDescriptorFlags_AllCritical;
- }
- }
- }
-#endif // !FEATURE_CORECLR
}
else if (strcmp(g_SecuritySafeCriticalAttribute + sizeof(g_SecurityNS), szAttributeName) == 0)
{
{
flags |= TokenSecurityDescriptorFlags_Transparent;
}
-#ifndef FEATURE_CORECLR
- else if (strcmp(g_SecurityRulesAttribute + sizeof(g_SecurityNS), szAttributeName) == 0)
- {
- const BYTE *pbAttributeBlob;
- ULONG cbAttributeBlob;
-
- if (FAILED(pmdImport->GetCustomAttributeAsBlob(
- currentAttribute,
- reinterpret_cast<const void **>(&pbAttributeBlob),
- &cbAttributeBlob)))
- {
- continue;
- }
-
- TokenSecurityDescriptorFlags securityRulesFlags =
- ParseSecurityRulesAttribute(pbAttributeBlob, cbAttributeBlob);
-
- flags |= securityRulesFlags;
- }
- else if (strcmp(g_SecurityTreatAsSafeAttribute + sizeof(g_SecurityNS), szAttributeName) == 0)
- {
- flags |= TokenSecurityDescriptorFlags_TreatAsSafe;
- }
-#endif // !FEATURE_CORECLR
}
}
return;
}
-#ifndef FEATURE_CORECLR
- TokenSecurityDescriptorTransparencyEtwEvents etw(this);
-#endif // !FEATURE_CORECLR
bool fIsSemanticallyCritical = false;
bool fIsSemanticallyTreatAsSafe = false;
// Encode a security rule set into token flags - this reverses GetSecurityRuleSet
inline TokenSecurityDescriptorFlags EncodeSecurityRuleSet(SecurityRuleSet ruleSet);
-#ifdef FEATURE_APTCA
-TokenSecurityDescriptorFlags ParseAptcaAttribute(const BYTE *pbAptcaBlob,
- DWORD cbAptcaBlob);
-#endif // FEATURE_APTCA
TokenSecurityDescriptorFlags ParseSecurityRulesAttribute(const BYTE *pbSecurityRulesBlob,
DWORD cbSecurityRulesBlob);
inline ModuleSecurityDescriptorFlags operator~(ModuleSecurityDescriptorFlags flags);
-#ifdef FEATURE_APTCA
-BOOL CheckAssemblyHasBeenKillBitted(LPASSEMBLYNAME pAssemblyName, ULARGE_INTEGER uliFileVersion);
-#endif
// Module security descriptor, this class contains static security information about the module
// this information will get persisted in the NGen image
// Get the rule set the assembly uses
inline SecurityRuleSet GetSecurityRuleSet();
-#ifndef FEATURE_CORECLR
- // Can fully trusted transparent code bypass verification
- inline BOOL CanTransparentCodeSkipVerification();
-#endif // !FEATURE_CORECLR
#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
// Does the assembly allow partially trusted callers
inline BOOL IsAPTCA();
#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
-#ifndef FEATURE_CORECLR
- BOOL AssemblyVersionRequiresLegacyTransparency();
-#endif // !FEATURE_CORECLR
private:
// Helper class which fires transparency calculation begin/end ETW events
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
// Non-CAS demands are not supported in CoreCLR
return TRUE;
-#else
- GCX_COOP();
-
- PsetCacheEntry *tokenSetIndexes[dclMaximumValue + 1];
- SecurityDeclarative::DetectDeclActionsOnToken(_mdToken, dwMethDeclFlags, tokenSetIndexes, pInternalImport);
- SecurityProperties sp(dwMethDeclFlags);
- if (!sp.FDemandsOnly())
- return FALSE;
-
- DWORD dwLocalAction;
- bool builtInCASPermsOnly = true;
- for (dwLocalAction = 0; dwLocalAction <= dclMaximumValue && builtInCASPermsOnly; dwLocalAction++)
- {
- if (tokenSetIndexes[dwLocalAction] != NULL)
- {
- builtInCASPermsOnly = builtInCASPermsOnly && (tokenSetIndexes[dwLocalAction]->ContainsBuiltinCASPermsOnly(dwLocalAction));
- }
- }
-
- return (builtInCASPermsOnly); // we only get here if there are only demands...so it suffices to return this value directly
-#endif
}
#ifndef DACCESS_COMPILE
}
return pClass->IsAllCritical()
-#ifndef FEATURE_CORECLR
- || pClass->IsCritical()
-#endif // !FEATURE_CORECLR
;
}
return !IsAllCritical() && !IsAllTransparent();
}
-#ifndef FEATURE_CORECLR
-inline BOOL ModuleSecurityDescriptor::CanTransparentCodeSkipVerification()
-{
- WRAPPER_NO_CONTRACT;
- VerifyDataComputed();
- return !!(m_flags & ModuleSecurityDescriptorFlags_SkipFullTrustVerification);
-}
-
-#endif // !FEATURE_CORECLR
-
-#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_CORESYSTEM)
inline BOOL ModuleSecurityDescriptor::IsAPTCA()
{
WRAPPER_NO_CONTRACT;
VerifyDataComputed();
return !!(m_flags & ModuleSecurityDescriptorFlags_IsAPTCA);
}
-#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#endif // defined(FEATURE_CORESYSTEM)
// Get the set of security rules that the assembly is using
inline SecurityRuleSet ModuleSecurityDescriptor::GetSecurityRuleSet()
{
return ::GetSecurityRuleSet(tokenFlags);
}
-#ifndef FEATURE_CORECLR
- else if (AssemblyVersionRequiresLegacyTransparency())
- {
- return SecurityRuleSet_Level1;
- }
-#endif // !FEATURE_CORECLR
else
{
// The assembly hasn't specified the rule set that it needs to use. We'll just use the default rule
// No action required
}
-#ifdef FEATURE_CAS_POLICY
-
-// static
-CrstStatic SecurityPolicy::s_crstPolicyInit;
-
-// static
-bool SecurityPolicy::s_fPolicyInitialized = false;
-
-void SecurityPolicy::InitPolicyConfig()
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- GCX_PREEMP();
-
- CrstHolder initializePolicy(&s_crstPolicyInit);
-
- if (!s_fPolicyInitialized)
- {
- // Note: These buffers should be at least as big as the longest possible
- // string that will be placed into them by the code below.
- const size_t cchcache = MAX_LONGPATH + sizeof( W("defaultusersecurity.config.cch") ) / sizeof( WCHAR ) + 1;
- const size_t cchconfig = MAX_LONGPATH + sizeof( W("defaultusersecurity.config.cch") ) / sizeof( WCHAR ) + 1;
- NewArrayHolder<WCHAR> cache(new WCHAR[cchcache]);
- NewArrayHolder<WCHAR> config(new WCHAR[cchconfig]);
-
- HRESULT hr = SecurityConfig::GetMachineDirectory(config, MAX_LONGPATH);
- if (FAILED(hr))
- ThrowHR(hr);
-
- wcscat_s( config, cchconfig, W("security.config") );
- wcscpy_s( cache, cchcache, config );
- wcscat_s( cache, cchcache, W(".cch") );
- SecurityConfig::InitData( SecurityConfig::MachinePolicyLevel, config, cache );
-
- hr = SecurityConfig::GetMachineDirectory(config, MAX_LONGPATH);
- if (FAILED(hr))
- ThrowHR(hr);
-
- wcscat_s( config, cchconfig, W("enterprisesec.config") );
- wcscpy_s( cache, cchcache, config );
- wcscat_s( cache, cchcache, W(".cch") );
- SecurityConfig::InitData( SecurityConfig::EnterprisePolicyLevel, config, cache );
-
- BOOL result = SecurityConfig::GetUserDirectory(config, MAX_LONGPATH);
- if (result) {
- wcscat_s( config, cchconfig, W("security.config") );
- wcscpy_s( cache, cchcache, config );
- wcscat_s( cache, cchcache, W(".cch") );
- SecurityConfig::InitData( SecurityConfig::UserPolicyLevel, config, cache );
- }
-
- s_fPolicyInitialized = true;
- }
-}
-#endif // FEATURE_CAS_POLICY
void SecurityPolicy::Start()
{
_ASSERTE(URLZONE_UNTRUSTED == Untrusted);
#endif // !FEATURE_PAL
-#ifdef FEATURE_CAS_POLICY
- s_crstPolicyInit.Init(CrstSecurityPolicyInit);
-
- SecurityConfig::Init();
-
- if (Security::IsProcessWideLegacyCasPolicyEnabled())
- {
- SecurityPolicy::InitPolicyConfig();
- }
-
- g_pCertificateCache = new CertificateCache();
-#endif // FEATURE_CAS_POLICY
}
void SecurityPolicy::Stop()
}
-#ifdef FEATURE_CAS_POLICY
-void SecurityPolicy::SaveCache()
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- Thread *pThread = GetThread();
- if (pThread == NULL)
- {
- BOOL fRet = FALSE;
- EX_TRY
- {
- // If CLR is hosted, a host can deny a thread during SetupThread call.
- if (IsShutdownSpecialThread())
- {
- SetupInternalThread();
- }
- else
- {
- SetupThread();
- }
- }
- EX_CATCH
- {
- fRet = TRUE;
- }
- EX_END_CATCH(SwallowAllExceptions);
- if (fRet)
- {
- return;
- }
- }
-
- SecurityConfig::SaveCacheData( SecurityConfig::MachinePolicyLevel );
- SecurityConfig::SaveCacheData( SecurityConfig::UserPolicyLevel );
- SecurityConfig::SaveCacheData( SecurityConfig::EnterprisePolicyLevel );
-
- SecurityConfig::Cleanup();
-}
-#endif
void QCALLTYPE SecurityPolicy::GetGrantedPermissions(QCall::ObjectHandleOnStack retGranted, QCall::ObjectHandleOnStack retDenied, QCall::StackCrawlMarkHandle stackmark)
{
MethodTable * pMT = MscorlibBinder::GetClass(CLASS__SECURITY_EXCEPTION);
-#ifdef FEATURE_CAS_POLICY
- MethodTable * pMTSecPerm = MscorlibBinder::GetClass(CLASS__SECURITY_PERMISSION);
-
- struct _gc {
- STRINGREF strDemandClass;
- OBJECTREF secPerm;
- STRINGREF strPermState;
- OBJECTREF secPermType;
- OBJECTREF secElement;
- } gc;
- memset(&gc, 0, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.strDemandClass = StringObject::NewString(wszDemandClass);
- if (gc.strDemandClass == NULL) COMPlusThrowOM();
- // Get the type seen by reflection
- gc.secPermType = pMTSecPerm->GetManagedClassObject();
- // Allocate the security exception object
- *pThrowable = AllocateObject(pMT);
- // Allocate the security permission object
- gc.secPerm = AllocateObject(pMTSecPerm);
-
- // Call the construtor with the correct flag
- MethodDescCallSite ctor(METHOD__SECURITY_PERMISSION__CTOR);
- ARG_SLOT arg3[2] = {
- ObjToArgSlot(gc.secPerm),
- (ARG_SLOT)dwFlags
- };
- ctor.Call(arg3);
-
- // Now, get the ToXml method
- MethodDescCallSite toXML(METHOD__SECURITY_PERMISSION__TOXML, &gc.secPerm);
- ARG_SLOT arg4 = ObjToArgSlot(gc.secPerm);
- gc.secElement = toXML.Call_RetOBJECTREF(&arg4);
-
- MethodDescCallSite toString(METHOD__SECURITY_ELEMENT__TO_STRING, &gc.secElement);
- ARG_SLOT arg5 = ObjToArgSlot(gc.secElement);
- gc.strPermState = toString.Call_RetSTRINGREF(&arg5);
-
- MethodDescCallSite exceptionCtor(METHOD__SECURITY_EXCEPTION__CTOR);
-
- ARG_SLOT arg6[4] = {
- ObjToArgSlot(*pThrowable),
- ObjToArgSlot(gc.strDemandClass),
- ObjToArgSlot(gc.secPermType),
- ObjToArgSlot(gc.strPermState),
- };
- exceptionCtor.Call(arg6);
-
- GCPROTECT_END();
-#else // FEATURE_CAS_POLICY
UNREFERENCED_PARAMETER(szDemandClass);
UNREFERENCED_PARAMETER(dwFlags);
*pThrowable = AllocateObject(pMT);
CallDefaultConstructor(*pThrowable);
-#endif // FEATURE_CAS_POLICY
}
DECLSPEC_NORETURN void SecurityPolicy::ThrowSecurityException(__in_z const char *szDemandClass, DWORD dwFlags)
GCPROTECT_END();
}
-#ifdef FEATURE_CAS_POLICY
-//-----------------------------------------------------------------------------------------
-//
-// Fire an ETW event to indicate that an evidence object has been generated for an assembly
-//
-// Arguments:
-// type - Type of evidence that was generated
-// pPEFile - PEFile for the assembly the evidence was for
-//
-
-// static
-void SecurityPolicy::TraceEvidenceGeneration(EvidenceType type, PEFile *pPEFile)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pPEFile));
- PRECONDITION(type >= kAssemblySupplied && type <= kZone);
- }
- CONTRACTL_END;
-
- const SString& strPath = pPEFile->GetILimage()->GetPath();
- FireEtwEvidenceGenerated(type,
- GetThread()->GetDomain()->GetId().m_dwId,
- strPath.IsEmpty() ? W("") : strPath.GetUnicode(),
- GetClrInstanceId());
-}
-
-// Called if CAS policy is not enabled, but we either have a host or a simple sandbox domain which will
-// determine the grant set of some evidence.
-OBJECTREF SecurityPolicy::ResolveGrantSet(OBJECTREF evidence, DWORD *pdwSpecialFlags, BOOL fCheckExecutionPermission)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(!GetAppDomain()->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled());
- PRECONDITION(CheckPointer(pdwSpecialFlags));
- }
- CONTRACTL_END;
-
- struct
- {
- OBJECTREF evidence;
- OBJECTREF grantSet;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- gc.evidence = evidence;
-
- GCPROTECT_BEGIN(gc);
-
- MethodDescCallSite resolve(METHOD__SECURITY_ENGINE__RESOLVE_GRANT_SET);
-
- ARG_SLOT args[3];
- args[0] = ObjToArgSlot(gc.evidence);
- args[1] = PtrToArgSlot(pdwSpecialFlags);
- args[2] = BoolToArgSlot(fCheckExecutionPermission);
-
- gc.grantSet = resolve.Call_RetOBJECTREF(args);
-
- GCPROTECT_END();
-
- return gc.grantSet;
-}
-
-// Resolve legacy CAS policy
-OBJECTREF SecurityPolicy::ResolveCasPolicy(OBJECTREF evidence,
- OBJECTREF reqdPset,
- OBJECTREF optPset,
- OBJECTREF denyPset,
- OBJECTREF* grantdenied,
- DWORD* dwSpecialFlags,
- BOOL checkExecutionPermission)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- PRECONDITION(GetAppDomain()->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled());
- PRECONDITION(SecurityPolicy::s_fPolicyInitialized);
- PRECONDITION(CheckPointer(dwSpecialFlags));
- } CONTRACTL_END;
-
-
- OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED);
-
- // If we got here, then we are going to do at least one security
- // check. Make sure security is initialized.
-
- struct _gc {
- OBJECTREF reqdPset; // Required Requested Permissions
- OBJECTREF optPset; // Optional Requested Permissions
- OBJECTREF denyPset; // Denied Permissions
- OBJECTREF evidence; // Object containing evidence
- OBJECTREF refRetVal;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
- gc.evidence = evidence;
- gc.reqdPset = reqdPset;
- gc.denyPset = denyPset;
- gc.optPset = optPset;
-
- GCPROTECT_BEGIN(gc);
-
- MethodDescCallSite resolvePolicy(METHOD__SECURITY_MANAGER__RESOLVE_CAS_POLICY);
-
- ARG_SLOT args[7];
- args[0] = ObjToArgSlot(gc.evidence);
- args[1] = ObjToArgSlot(gc.reqdPset);
- args[2] = ObjToArgSlot(gc.optPset);
- args[3] = ObjToArgSlot(gc.denyPset);
- args[4] = PtrToArgSlot(grantdenied);
- args[5] = PtrToArgSlot(dwSpecialFlags);
- args[6] = BoolToArgSlot(checkExecutionPermission);
-
- {
- // Elevate thread's allowed loading level. This can cause load failures if assemblies loaded from this point on require
- // any assemblies currently being loaded.
- OVERRIDE_LOAD_LEVEL_LIMIT(FILE_ACTIVE);
- // call policy resolution routine in managed code
- gc.refRetVal = resolvePolicy.Call_RetOBJECTREF(args);
- }
-
- GCPROTECT_END();
- return gc.refRetVal;
-}
-#endif // FEATURE_CAS_POLICY
#endif // CROSSGEN_COMPILE
#ifndef CROSSGEN_COMPILE
-#ifdef FEATURE_CAS_POLICY
-SecZone QCALLTYPE SecurityPolicy::CreateFromUrl(LPCWSTR wszUrl)
-{
- QCALL_CONTRACT;
-
- SecZone dwZone = NoZone;
-
- BEGIN_QCALL;
-
- if (wszUrl != NULL)
- {
- dwZone = SecurityPolicy::MapUrlToZone(wszUrl);
- }
-
- END_QCALL;
-
- return dwZone;
-}
-
-HRESULT
-GetSecurityPolicyRegKey(
- __out WCHAR **ppszSecurityPolicy)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- INJECT_FAULT(return E_OUTOFMEMORY);
- }
- CONTRACTL_END;
-
- DWORD dwLen = 0;
-
- HRESULT hr = g_pCLRRuntime->GetVersionString(NULL, &dwLen);
- if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- return hr;
-
- size_t bufSize = _countof(FRAMEWORK_REGISTRY_KEY_W) + 1 + dwLen + _countof(KEY_COM_SECURITY_POLICY);
- NewArrayHolder<WCHAR> key(new(nothrow) WCHAR[bufSize]);
- if (key == NULL)
- return E_OUTOFMEMORY;
- wcscpy_s(key, bufSize, FRAMEWORK_REGISTRY_KEY_W W("\\"));
-
- hr = g_pCLRRuntime->GetVersionString(key + NumItems(FRAMEWORK_REGISTRY_KEY_W), &dwLen);
- if (FAILED(hr))
- return hr;
-
- size_t offset = _countof(FRAMEWORK_REGISTRY_KEY_W)+dwLen-1;
- wcscpy_s(key + offset, bufSize - offset, KEY_COM_SECURITY_POLICY);
- key.SuppressRelease();
- *ppszSecurityPolicy = key;
- return S_OK;
-} // GetSecurityPolicyRegKey
-
-HRESULT SecurityPolicy::ApplyCustomZoneOverride(SecZone *pdwZone)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- PRECONDITION(*pdwZone >= NumZones);
- INJECT_FAULT(return E_OUTOFMEMORY);
- }
- CONTRACTL_END;
-
- NewArrayHolder<WCHAR> key(NULL);
- HRESULT hr = GetSecurityPolicyRegKey(&key);
- if (FAILED(hr))
- return hr;
- if (REGUTIL::GetLong(KEY_COM_SECURITY_ZONEOVERRIDE, 0, key, HKEY_POLICY_ROOT) == 1)
- *pdwZone=Internet;
- return S_OK;
-} // ApplyCustomZoneOverride
-
-//---------------------------------------------------------------------------------------
-//
-// Determine which security zone a URL belongs to
-//
-// Arguments:
-// wszUrl - URL to get zone information about
-//
-// Return Value:
-// Security zone the URL belongs to
-//
-// Notes:
-// If the runtime cannot map the URL, we'll return NoZone. A mapping to a zone that the VM doesn't
-// know about will cause us to check the TreatCustomZonesAsInternetZone registry key and potentially
-// map it back to the Internet zone.
-//
-
-// static
-SecZone SecurityPolicy::MapUrlToZone(__in_z LPCWSTR wszUrl)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(wszUrl != NULL);
- }
- CONTRACTL_END;
-
- SecZone dwZone = NoZone;
-
- ReleaseHolder<IInternetSecurityManager> securityManager = NULL;
- HRESULT hr = CoInternetCreateSecurityManager(NULL, &securityManager, 0);
-
- if (SUCCEEDED(hr))
- {
- _ASSERTE(sizeof(SecZone) == sizeof(DWORD));
- hr = securityManager->MapUrlToZone(wszUrl, reinterpret_cast<DWORD *>(&dwZone), 0);
-
- if (SUCCEEDED(hr))
- {
- // if this is a custom zone, see if the user wants us to map it back to the Internet zone
- if (dwZone >= NumZones)
- {
- SecZone dwMappedZone = dwZone;
- hr = ApplyCustomZoneOverride(&dwMappedZone);
- if (SUCCEEDED(hr))
- {
- dwZone = dwMappedZone;
- }
- }
- }
- else
- {
- dwZone = NoZone;
- }
- }
-
- return dwZone;
-}
-#endif //FEATURE_CAS_POLICY
BOOL QCALLTYPE SecurityPolicy::IsLocalDrive(LPCWSTR wszPath)
{
{
QCALL_CONTRACT;
-#if !defined(FEATURE_CORECLR)
- BEGIN_QCALL;
-
- WCHAR networkName[MAX_LONGPATH];
- DWORD networkNameSize = MAX_LONGPATH;
- ZeroMemory( networkName, sizeof( networkName ) );
-
- UINT driveType = WszGetDriveType( wszDriveLetter );
- if (driveType == DRIVE_REMOVABLE ||
- driveType == DRIVE_FIXED ||
- driveType == DRIVE_CDROM ||
- driveType == DRIVE_RAMDISK)
- {
- retDeviceName.Set( wszDriveLetter );
- goto lExit;
- }
-
- if (WszWNetGetConnection(wszDriveLetter, networkName, &networkNameSize) != NO_ERROR)
- {
- goto lExit;
- }
-
- retDeviceName.Set( networkName );
-
-lExit: ;
-
- END_QCALL;
-#endif // !FEATURE_CORECLR
-}
-
-#ifdef FEATURE_CAS_POLICY
-
-//
-// Fire the ETW event that signals that a specific type of evidence has been created
-//
-// Arguments:
-// pPEFile - PEFile the evidence was generated for
-// type - type of evidence generated
-//
-
-// static
-void QCALLTYPE SecurityPolicy::FireEvidenceGeneratedEvent(PEFile *pPEFile,
- EvidenceType type)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION(CheckPointer(pPEFile));
- }
- CONTRACTL_END;
-
- BEGIN_QCALL;
-
- TraceEvidenceGeneration(type, pPEFile);
-
- END_QCALL;
}
-// static
-
-void QCALLTYPE SecurityPolicy::GetEvidence(QCall::AssemblyHandle pAssembly, QCall::ObjectHandleOnStack retEvidence)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- IAssemblySecurityDescriptor *pSecDesc = pAssembly->GetSecurityDescriptor();
-
- _ASSERTE(pSecDesc->GetDomain() == GetAppDomain());
-
- GCX_COOP();
- if (pSecDesc->IsEvidenceComputed())
- retEvidence.Set(pSecDesc->GetAdditionalEvidence());
- else
- retEvidence.Set(pSecDesc->GetEvidence());
-
- END_QCALL;
-}
-
-//---------------------------------------------------------------------------------------
-//
-// Determine if an evidence collection has a delay generated strong name evidence object
-// which was used during the process of demand evaluation.
-//
-// Arguments:
-// orEvidence - evidence collection to examine
-//
-// Return Value:
-// true if orEvidence contains unverified strong name evidence which has been used to generate a grant,
-// false if orEvidence does not contain strong name evidence or that evidence was verified / not used
-//
-
-// static
-BOOL SecurityPolicy::WasStrongNameEvidenceUsed(OBJECTREF orEvidence)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- // If we don't have any evidence, then there isn't any strong name evidence, and therefore it couldn't
- // have been used.
- if (orEvidence == NULL)
- {
- return FALSE;
- }
-
- BOOL fStrongNameEvidenceWasUsed = FALSE;
-
- GCPROTECT_BEGIN(orEvidence);
-
- MethodDescCallSite wasSnEvidenceUsed(METHOD__EVIDENCE__WAS_STRONGNAME_EVIDENCE_USED);
-
- ARG_SLOT args[] = { ObjToArgSlot(orEvidence) };
- fStrongNameEvidenceWasUsed = !!wasSnEvidenceUsed.Call_RetBool(args);
-
- GCPROTECT_END();
-
- return fStrongNameEvidenceWasUsed;
-}
-#endif // FEATURE_CAS_POLICY
FCIMPL0(void, SecurityPolicy::IncrementOverridesCount)
{
}
FCIMPLEND
-#ifdef FEATURE_CAS_POLICY
-//
-// Evidence QCalls
-//
-
-//---------------------------------------------------------------------------------------
-//
-// Get the assembly level permission requests
-//
-// Arguments:
-// pAssembly - Assembly to get the declarative security of
-// retMinimumPermissions - [out] RequestMinimum set of the assembly
-// retOptionalPermissions - [out] RequestOptional set of the assembly
-// retRefusedPermissions - [out] RequestRefuse set of the assembly
-//
-
-// static
-void QCALLTYPE SecurityPolicy::GetAssemblyPermissionRequests(QCall::AssemblyHandle pAssembly,
- QCall::ObjectHandleOnStack retMinimumPermissions,
- QCall::ObjectHandleOnStack retOptionalPermissions,
- QCall::ObjectHandleOnStack retRefusedPermissions)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
-
- TraceEvidenceGeneration(kPermissionRequest, pAssembly->GetFile());
- AssemblySecurityDescriptor *pSecurityDescriptor = static_cast<AssemblySecurityDescriptor*>(pAssembly->GetSecurityDescriptor());
-
- _ASSERTE(pSecurityDescriptor->GetDomain()->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled());
-
- struct
- {
- OBJECTREF objMinimumPermissions;
- OBJECTREF objOptionalPermissions;
- OBJECTREF objRefusedPermissions;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCX_COOP();
- GCPROTECT_BEGIN(gc);
-
- gc.objMinimumPermissions = pSecurityDescriptor->GetRequestedPermissionSet(&gc.objOptionalPermissions,
- &gc.objRefusedPermissions);
-
- retMinimumPermissions.Set(gc.objMinimumPermissions);
- retOptionalPermissions.Set(gc.objOptionalPermissions);
- retRefusedPermissions.Set(gc.objRefusedPermissions);
-
- GCPROTECT_END();
-
- END_QCALL;
-}
-
-//---------------------------------------------------------------------------------------
-//
-// Get the serialized evidence stream from an assembly
-//
-// Arguments:
-// pPEFile - PEFile to load the evidence stream from
-// retSerializedEvidence - [out] contents of the serialized evidence
-//
-
-// static
-void QCALLTYPE SecurityPolicy::GetAssemblySuppliedEvidence(PEFile *pPEFile,
- QCall::ObjectHandleOnStack retSerializedEvidence)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION(CheckPointer(pPEFile));
- }
- CONTRACTL_END;
-
- BEGIN_QCALL;
-
- DWORD cbResource;
- BYTE *pbResource;
-
- // Load the resource from the PE file. We do not need to free this memory, since we're getting a direct
- // pointer into the PE contents rather than a buffer.
- TraceEvidenceGeneration(kAssemblySupplied, pPEFile);
- BOOL fFoundSerializedEvidence = pPEFile->GetResource("Security.Evidence",
- &cbResource,
- &pbResource,
- NULL,
- NULL,
- NULL,
- NULL,
- FALSE,
- TRUE,
- NULL,
- NULL);
-
- if (fFoundSerializedEvidence)
- {
- retSerializedEvidence.SetByteArray(pbResource, cbResource);
- }
-
- END_QCALL;
-}
-
-//---------------------------------------------------------------------------------------
-//
-// Get the zone and URL that the PEFile was loaded from
-//
-// Arguments:
-// pPEFile - PEFile to load the evidence stream from
-// pZone - [out] SecurityZone the file was loaded from
-// retUrl - [out] URL the file was loaded from
-
-// static
-void QCALLTYPE SecurityPolicy::GetLocationEvidence(PEFile *pPEFile,
- SecZone *pZone,
- QCall::StringHandleOnStack retUrl)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION(CheckPointer(pPEFile));
- }
- CONTRACTL_END;
-
- BEGIN_QCALL;
-
- StackSString ssCodeBase;
- BYTE pbUniqueID[MAX_SIZE_SECURITY_ID];
- DWORD cbUniqueID = COUNTOF(pbUniqueID);
-
- // The location information is used to create Site, Url, and Zone evidence so fire all three events
- TraceEvidenceGeneration(kSite, pPEFile);
- TraceEvidenceGeneration(kUrl, pPEFile);
- TraceEvidenceGeneration(kZone, pPEFile);
-
- pPEFile->GetSecurityIdentity(ssCodeBase, pZone, 0, pbUniqueID, &cbUniqueID);
-
- retUrl.Set(ssCodeBase);
-
- END_QCALL;
-}
-
-//---------------------------------------------------------------------------------------
-//
-// Get the X.509 certificate that the PE file's Authenticode signature was created with
-//
-// Arguments:
-// pPEFile - PEFile to load the evidence stream from
-// retCertificate - [out] certificate that signed the file
-
-// static
-void QCALLTYPE SecurityPolicy::GetPublisherCertificate(PEFile *pPEFile,
- QCall::ObjectHandleOnStack retCertificate)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION(CheckPointer(pPEFile));
- }
- CONTRACTL_END;
-
- BEGIN_QCALL;
-
- TraceEvidenceGeneration(kPublisher, pPEFile);
- COR_TRUST *pAuthenticodeSignature = pPEFile->GetAuthenticodeSignature();
- if (pAuthenticodeSignature != NULL && pAuthenticodeSignature->pbSigner != NULL)
- {
- retCertificate.SetByteArray(pAuthenticodeSignature->pbSigner, pAuthenticodeSignature->cbSigner);
- }
-
- END_QCALL;
-}
-
-//---------------------------------------------------------------------------------------
-//
-// Get the components of an assembly's strong name to generate strong name evidence with
-//
-// Arguments:
-// pAssembly - assembly to get the strong name of
-// retPublicKeyBlob - [out] public component of the key the assembly is signed with
-// retSimpleName - [out] simple name of the file
-// piMajorVersion - [out] major version
-// piMinorVersion - [out] minor version
-// piBuild - [out] build
-// piRevision - [out] revision
-//
-// Notes:
-// retPublicKeyBlob will be null for a simply named assembly
-//
-
-// static
-void QCALLTYPE SecurityPolicy::GetStrongNameInformation(QCall::AssemblyHandle pAssembly,
- QCall::ObjectHandleOnStack retPublicKeyBlob,
- QCall::StringHandleOnStack retSimpleName,
- USHORT *piMajorVersion,
- USHORT *piMinorVersion,
- USHORT *piBuild,
- USHORT *piRevision)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION(CheckPointer(piMajorVersion));
- PRECONDITION(CheckPointer(piMinorVersion));
- PRECONDITION(CheckPointer(piBuild));
- PRECONDITION(CheckPointer(piRevision));
- }
- CONTRACTL_END;
-
- BEGIN_QCALL;
-
- PEAssembly *pPEAssembly = pAssembly->GetFile();
- TraceEvidenceGeneration(kStrongName, pPEAssembly);
-
- DWORD cbPublicKey;
- const BYTE *pbPublicKey = reinterpret_cast<const BYTE*>(pPEAssembly->GetPublicKey(&cbPublicKey));
-
- if (pbPublicKey != NULL && cbPublicKey > 0)
- {
- pPEAssembly->GetVersion(piMajorVersion, piMinorVersion, piBuild, piRevision);
- retPublicKeyBlob.SetByteArray(pbPublicKey, cbPublicKey);
- retSimpleName.Set(pPEAssembly->GetSimpleName());
- }
- else
- {
- GCX_COOP();
- retPublicKeyBlob.Set(NULL);
- }
-
- END_QCALL;
-}
-
-#endif // FEATURE_CAS_POLICY
#ifdef FEATURE_FUSION
static void GetFusionNameFromAssemblyQualifiedTypeName(LPCWSTR pAssemblyQualifedTypeName, IAssemblyName ** ppFusionName)
class NDirect;
class SystemDomain;
class AssemblySecurityDescriptor;
-#ifndef FEATURE_CORECLR
-class PEFileSecurityDescriptor;
-#endif
class SharedSecurityDescriptor;
class SecurityStackWalkData;
class DemandStackWalk;
#endif // #ifdef FEATURE_IMPERSONATION
FCDECL0(FC_BOOL_RET, IsDefaultThreadSecurityInfo);
-#ifdef FEATURE_CAS_POLICY
- SecZone QCALLTYPE CreateFromUrl(LPCWSTR wszUrl);
-#endif // FEATURE_CAS_POLICY
void QCALLTYPE _GetLongPathName(LPCWSTR wszPath, QCall::StringHandleOnStack retLongPath);
BOOL QCALLTYPE IsLocalDrive(LPCWSTR wszPath);
FCDECL0(VOID, DecrementAssertCount);
-#ifdef FEATURE_CAS_POLICY
- //
- // Evidence QCalls
- //
-
-//public:
- void QCALLTYPE FireEvidenceGeneratedEvent(PEFile *pPEFile, EvidenceType type);
-
- void QCALLTYPE GetEvidence(QCall::AssemblyHandle pAssembly, QCall::ObjectHandleOnStack retEvidence);
-
- void QCALLTYPE GetAssemblyPermissionRequests(QCall::AssemblyHandle pAssembly,
- QCall::ObjectHandleOnStack retMinimumPermissions,
- QCall::ObjectHandleOnStack retOptionalPermissions,
- QCall::ObjectHandleOnStack retRefusedPermissions);
-
- void QCALLTYPE GetAssemblySuppliedEvidence(PEFile *pPEFile, QCall::ObjectHandleOnStack retSerializedEvidence);
-
- void QCALLTYPE GetLocationEvidence(PEFile *pPEFile, SecZone *pZone, QCall::StringHandleOnStack retUrl);
-
- void QCALLTYPE GetPublisherCertificate(PEFile *pPEFile, QCall::ObjectHandleOnStack retCertificate);
-
- void QCALLTYPE GetStrongNameInformation(QCall::AssemblyHandle pAssembly,
- QCall::ObjectHandleOnStack retPublicKeyBlob,
- QCall::StringHandleOnStack retSimpleName,
- USHORT *piMajorVersion,
- USHORT *piMinorVersion,
- USHORT *piBuild,
- USHORT *piRevision);
-#endif // FEATURE_CAS_POLICY
//private:
// -----------------------------------------------------------
// <currently unused> @TODO: shouldn't EEShutDownHelper call this?
void Stop();
-#ifdef FEATURE_CAS_POLICY
- // Saves security cache data
- // Callers:
- // EEShutDownHelper
- void SaveCache();
-#endif
// -----------------------------------------------------------
BOOL CanSkipVerification(DomainAssembly * pAssembly);
-#ifdef FEATURE_CAS_POLICY
- void TraceEvidenceGeneration(EvidenceType type, PEFile *pPEFile);
-
- // Map a URL to a zone, applying any user supplied policy
- SecZone MapUrlToZone(__in_z LPCWSTR wszUrl);
-
- // Apply user supplied policy to a zone
- HRESULT ApplyCustomZoneOverride(SecZone *pdwZone);
-
- // Determine what the grant set of an assembly is
- OBJECTREF ResolveGrantSet(OBJECTREF evidence, OUT DWORD *pdwSpecialFlags, BOOL fcheckExecutionPermission);
-
- // Resolve legacy CAS policy on the assembly
- // Callers:
- // SecurityDescriptor::ResolveWorker
- OBJECTREF ResolveCasPolicy(OBJECTREF evidence,
- OBJECTREF reqdPset,
- OBJECTREF optPset,
- OBJECTREF denyPset,
- OBJECTREF* grantdenied,
- DWORD* pdwSpecialFlags,
- BOOL checkExecutionPermission);
-
- // Load the policy config/cache files at EE startup
- void InitPolicyConfig();
-
- BOOL WasStrongNameEvidenceUsed(OBJECTREF evidence);
-#endif
// Like WszGetLongPathName, but it works with nonexistant files too
size_t GetLongPathNameHelper( const WCHAR* wszShortPath, SString& wszBuffer);
-#ifdef FEATURE_CAS_POLICY
- extern CrstStatic s_crstPolicyInit;
- extern bool s_fPolicyInitialized;
-#endif // FEATURE_CAS_POLICY
}
struct SharedPermissionObjects
// Callers:
// CanAccess (ReflectionInvocation)
// ReflectionSerialization::GetSafeUninitializedObject
-#ifdef FEATURE_APTCA
- // SecurityDeclarative::DoUntrustedCallerChecks
-#endif // FEATURE_APTCA
static void DemandSet(SecurityStackWalkType eType, OBJECTREF demand);
// Native version of PermissionSet.Demand() that delays instantiating the PermissionSet object
}
CONTRACTL_END;
-#if !defined(CROSSGEN_COMPILE) && defined(FEATURE_CAS_POLICY)
- if (NingenEnabled())
- return;
-
- GCX_COOP();
-
- OBJECTREF permSet = NULL;
- GCPROTECT_BEGIN(permSet);
-
- Security::GetPermissionInstance(&permSet, SECURITY_FULL_TRUST);
- Security::DemandSet(SSWT_LATEBOUND_LINKDEMAND, permSet);
-
- GCPROTECT_END();
-#endif // !CROSSGEN_COMPILE && FEATURE_CAS_POLICY
}
// static
return TRUE;
}
-#ifdef FEATURE_CORECLR
// On the coreCLR, a method can be transparent even if the containing type is marked Critical.
// This will happen when that method is an override of a base transparent method, and the type that
// contains the override is marked Critical. And that's the only case it can happen.
{
return TRUE;
}
-#endif // FEATURE_CORECLR
// an attached profiler may wish to have these checks suppressed
if (Security::BypassSecurityChecksForProfiler(pCurrentMD))
return TRUE;
}
-#ifdef FEATURE_CORECLR
// On CoreCLR only critical code may ever assert - there are no compatibility reasons to allow
// transparent asserts.
return FALSE;
-#else // !FEATURE_CORECLR
- // We must be in a heterogenous AppDomain for transparent asserts to work
- if (GetAppDomain()->GetSecurityDescriptor()->IsHomogeneous())
- {
- return FALSE;
- }
-
- ModuleSecurityDescriptor *pMSD = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pMD->GetAssembly());
-
- // Only assemblies whose version requires them to use legacy transparency (rather than assemblies which
- // get legacy transparency via RuleSet.Level1) can assert from transparent code
- if (!pMSD->AssemblyVersionRequiresLegacyTransparency())
- {
- return FALSE;
- }
-
- // Finally, the assembly must not have had any of the transparency attributes on it
- const TokenSecurityDescriptorFlags transparencyAwareFlags =
- TokenSecurityDescriptorFlags_AllCritical | // [SecurityCritical(SecurityCriticalScope.All)]
- TokenSecurityDescriptorFlags_Critical | // [SecurityCritical]
- TokenSecurityDescriptorFlags_SafeCritical | // [SecuritySafeCritical]
- TokenSecurityDescriptorFlags_Transparent | // [SecurityTransparent]
- TokenSecurityDescriptorFlags_TreatAsSafe; // [SecurityTreatAsSafe]
- TokenSecurityDescriptorFlags moduleAttributes = pMSD->GetTokenFlags();
- if ((moduleAttributes & transparencyAwareFlags) != TokenSecurityDescriptorFlags_None)
- {
- return FALSE;
- }
-
- return TRUE;
-#endif // FEATURE_CORECLR
}
// Functor class to aid in determining if a type requires a transparency check
CorInfoCanSkipVerificationResult canSkipVerif = hasSkipVerificationPermisson ? CORINFO_VERIFICATION_CAN_SKIP : CORINFO_VERIFICATION_CANNOT_SKIP;
-#ifndef FEATURE_CORECLR
- // also check to see if the method is marked transparent
- if (hasSkipVerificationPermisson)
- {
- if (pDomainAssembly == GetAppDomain()->GetAnonymouslyHostedDynamicMethodsAssembly())
- {
- // This assembly is FullTrust. However, it cannot contain unverifiable code.
- // The JIT compiler is not hardened to deal with invalid code. Hence, we cannot
- // return CORINFO_VERIFICATION_RUNTIME_CHECK for IL that could have been generated
- // by a low-trust assembly.
- canSkipVerif = CORINFO_VERIFICATION_CANNOT_SKIP;
- }
- // also check to see if the method is marked transparent
- else if (SecurityTransparent::IsMethodTransparent(pMD))
- {
- // If the assembly requested that even its transparent members not be verified, then we can skip
- // verification. Otherwise, we need to either inject a runtime demand in the v2 model, or fail
- // verification in the v4 model.
- ModuleSecurityDescriptor *pModuleSecDesc = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pMD->GetAssembly());
- if (pModuleSecDesc->CanTransparentCodeSkipVerification())
- {
- canSkipVerif = CORINFO_VERIFICATION_CAN_SKIP;
- }
- else if (pMD->GetAssembly()->GetSecurityTransparencyBehavior()->CanTransparentCodeSkipVerification())
- {
- canSkipVerif = CORINFO_VERIFICATION_RUNTIME_CHECK;
- }
- else
- {
- canSkipVerif = CORINFO_VERIFICATION_CANNOT_SKIP;
- }
- }
- }
-#endif //FEATURE_CORECLR
return canSkipVerif;
}
{
// In CoreCLR, do not enable transparency checks here. We depend on this method being "honest" in
// JITCanSkipVerification to skip transparency checks on profile assemblies.
-#ifndef FEATURE_CORECLR
- ModuleSecurityDescriptor *pMsd = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pAssembly->GetAssembly());
- if (pMsd->IsAllTransparent() &&
- pAssembly->GetAssembly()->GetSecurityTransparencyBehavior()->CanTransparentCodeSkipVerification())
- {
- canSkipVerif = CORINFO_VERIFICATION_RUNTIME_CHECK;
- }
-#endif // !FEATURE_CORECLR
}
return canSkipVerif;
// In coreclr, we modified the logic in the callout to also do some transparency method access checks
// These checks need to happen regardless of trust level and we shouldn't be bailing out early
// just because we happen to be in Full Trust
-#ifndef FEATURE_CORECLR
- // See if we need to process this callout for real, or if we can bail out early before setting up a HMF,
- // and spending a lot of time processing the transparency evaluation. The simplest case where we can do
- // this is if the caller is critical. In that case, we know that the caller is allowed to do whatever
- // it wants, so we quit out.
- //
- // Additionally, if the caller is using SecurityRuleSet.Level1, which turns transparency violations into
- // security demands, we can bail out early if we know for sure all demands will succeed on the current
- // call stack. (Note: this remains true as long as we don't start generating callouts for transparent
- // level 1 calling critical level 1, or transparent level 1 doing an assert, which are the only two
- // violations which do not succeed in the face of a successful demand).
- if (pCallerMD->IsCritical())
- {
- return true;
- }
- else
- {
- // The caller is transparent, so let's see if demands can cause transparency violations to succeed,
- // and also if all demands issued from this context will succeed.
- const SecurityTransparencyBehavior *pCallerTransparency = pCallerMD->GetAssembly()->TryGetSecurityTransparencyBehavior();
- if (pCallerTransparency != NULL &&
- pCallerTransparency->CanTransparentCodeCallLinkDemandMethods() &&
- SecurityStackWalk::HasFlagsOrFullyTrustedIgnoreMode(0))
- {
- return true;
- }
- }
-#endif // !FEATURE_CORECLR
return false;
}
}
CONTRACTL_END
-#ifdef FEATURE_CAS_POLICY
- GCX_COOP();
- // check to see if the method that does the Load(byte[] ) is transparent
- if (IsMethodTransparent(pCallerMD))
- {
- Assembly* pLoadedAssembly = pLoadedSecDesc->GetAssembly();
- // check to see if the byte[] being loaded is critical, i.e. not Transparent
- if (!ModuleSecurityDescriptor::IsMarkedTransparent(pLoadedAssembly))
- {
- // if transparent code loads a byte[] that is critical, need to inject appropriate demands
- if (pLoadedSecDesc->IsFullyTrusted()) // if the loaded code is full-trust
- {
- // do a full-demand for Full-Trust
- OBJECTREF permSet = NULL;
- GCPROTECT_BEGIN(permSet);
- Security::GetPermissionInstance(&permSet, SECURITY_FULL_TRUST);
- Security::DemandSet(SSWT_LATEBOUND_LINKDEMAND, permSet);
- GCPROTECT_END();// do a full-demand for Full-Trust
- }
- else
- {
- // otherwise inject a Demand for permissions being granted?
- struct _localGC {
- OBJECTREF granted;
- OBJECTREF denied;
- } localGC;
- ZeroMemory(&localGC, sizeof(localGC));
-
- GCPROTECT_BEGIN(localGC);
- {
- localGC.granted = pLoadedSecDesc->GetGrantedPermissionSet(&(localGC.denied));
- Security::DemandSet(SSWT_LATEBOUND_LINKDEMAND, localGC.granted);
- }
- GCPROTECT_END();
- }
- }
- }
-#endif // FEATURE_CAS_POLICY
}
static void ConvertLinkDemandToFullDemand(MethodDesc* pCallerMD, MethodDesc* pCalleeMD)
&gc.refMethodCasDemands,
&gc.refMethodNonCasDemands);
-#ifdef FEATURE_APTCA
- BOOL fCallerIsAPTCA = pCallerMD->GetAssembly()->AllowUntrustedCaller();
-
- if ((linktimeCheckReason & LinktimeCheckReason_AptcaCheck))
- {
- if (fCallerIsAPTCA &&
- Security::IsUntrustedCallerCheckNeeded(pCalleeMD, pCallerMD->GetAssembly()))
- {
-#ifdef _DEBUG
- if (g_pConfig->LogTransparencyErrors())
- {
- SecurityTransparent::LogTransparencyError(pCallerMD, "Transparent method calling an APTCA protected assembly", pCalleeMD);
- }
- if (!g_pConfig->DisableTransparencyEnforcement())
-#endif // _DEBUG
- {
- // Depending on the transparency model, we need to either fail the attempt to call a method
- // protected with the APTCA link demand, or conver it to a full demand. Note that we need to
- // upgrade to a full demand if either the caller of callee are in v2 mode, the APTCA check is
- // conceptually a link demand, and for link demands we do the conversion if either assembly is
- // using the v2 rules.
- if (pCallerMD->GetAssembly()->GetSecurityTransparencyBehavior()->CanTransparentCodeCallLinkDemandMethods() ||
- pCalleeMD->GetAssembly()->GetSecurityTransparencyBehavior()->CanTransparentCodeCallLinkDemandMethods())
- {
- OBJECTREF permSet = NULL;
- GCPROTECT_BEGIN(permSet);
- Security::GetPermissionInstance(&permSet, SECURITY_FULL_TRUST);
- Security::DemandSet(SSWT_LATEBOUND_LINKDEMAND, permSet);
- GCPROTECT_END();
- }
- else
- {
- ::ThrowMethodAccessException(pCallerMD, pCalleeMD, FALSE, IDS_E_TRANSPARENT_CALL_LINKDEMAND);
- }
- }
- }
- }
-#endif // FEATURE_APTCA
// The following logic turns link demands on the target method into full stack walks
if (pCallerMD->GetAssembly()->GetSecurityTransparencyBehavior()->CanTransparentCodeCallUnmanagedCode())
{
-#ifdef FEATURE_APTCA
- if (fCallerIsAPTCA)
- {
- // if the caller assembly is APTCA, then only inject this demand, for NON-APTCA we will allow
- // calls to native code
- // NOTE: the JIT would have already performed the LinkDemand for this anyways
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_UNMANAGED_CODE);
- }
-#endif // FEATURE_APTCA
}
else
{
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
// We only enforce delegate binding rules in partial trust
if (GetAppDomain()->GetSecurityDescriptor()->IsFullyTrusted())
return;
TypeString::AppendType(strDelegateType, pDelegateMT, TypeString::FormatNamespace | TypeString::FormatAngleBrackets| TypeString::FormatSignature);
COMPlusThrowHR(COR_E_METHODACCESS, IDS_E_DELEGATE_BINDING_TRANSPARENCY, strDelegateType.GetUnicode(), strMethod.GetUnicode());
-#endif // FEATURE_CORECLR
}
#endif // CROSSGEN_COMPILE
}
};
-#ifndef FEATURE_CORECLR
-
-//---------------------------------------------------------------------------------------
-//
-// Transparency behavior implementation for v2 assemblies
-//
-
-class LegacyTransparencyBehaviorImpl : public ISecurityTransparencyImpl
-{
-public:
- // Get bits that indicate how transparency should behave in different situations
- virtual SecurityTransparencyBehaviorFlags GetBehaviorFlags() const
- {
- LIMITED_METHOD_CONTRACT;
- return SecurityTransparencyBehaviorFlags_IntroducedCriticalsMayAddTreatAsSafe |
- SecurityTransparencyBehaviorFlags_OpportunisticIsSafeCriticalMethods |
- SecurityTransparencyBehaviorFlags_PartialTrustImpliesAllTransparent |
- SecurityTransparencyBehaviorFlags_PublicImpliesTreatAsSafe |
- SecurityTransparencyBehaviorFlags_TransparentCodeCanCallLinkDemand |
- SecurityTransaprencyBehaviorFlags_TransparentCodeCanCallUnmanagedCode |
- SecurityTransparencyBehaviorFlags_TransparentCodeCanSkipVerification |
- SecurityTransparencyBehaviorFlags_UnsignedImpliesAPTCA;
- }
-
- // Legacy transparency field behavior mappings:
- // Attribute Behavior
- // -----------------------------------------------------
- // Critical (any) Critical
- // SafeCritical Safe critical
- // TAS (no critical) No effect
- // TAS (with any critical) Safe critical
- virtual FieldSecurityDescriptorFlags MapFieldAttributes(TokenSecurityDescriptorFlags tokenFlags) const
- {
- WRAPPER_NO_CONTRACT;
-
- // Legacy transparency behaves the same for fields as the current transparency model, so we just forward
- // this call to that implementation.
- TransparencyBehaviorImpl forwardImpl;
- return forwardImpl.MapFieldAttributes(tokenFlags);
- }
-
-
- // Legacy transparency method behavior mappings:
- // Attribute Behavior
- // -----------------------------------------------------
- // Critical (any) Critical
- // SafeCritical Safe critical
- // TAS (no critical) No effect
- // TAS (with any critical) Safe critical
- virtual MethodSecurityDescriptorFlags MapMethodAttributes(TokenSecurityDescriptorFlags tokenFlags) const
- {
- WRAPPER_NO_CONTRACT;
-
- // Legacy transparency behaves the same for methods as the current transparency model, so we just forward
- // this call to that implementation.
- TransparencyBehaviorImpl forwardImpl;
- return forwardImpl.MapMethodAttributes(tokenFlags);
- }
-
- // Legacy transparency module behavior mappings:
- // Attribute Behavior
- // -----------------------------------------------------
- // APTCA APTCA
- // ConditionlAPTCA Exception
- // Critical (scoped) Mixed transparency
- // Critical (all) All critical
- // SafeCritical All safe critical
- // TAS (no critical) No effect
- // TAS (with scoped critical) No effect
- // TAS (with all critical) All safe critical
- // Transparent All transparent
- //
- // Having no transparent, critical, or safe critical attributes means that the assembly should have all
- // transparent types and all safe critical methods.
- virtual ModuleSecurityDescriptorFlags MapModuleAttributes(TokenSecurityDescriptorFlags tokenFlags) const
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- SO_INTOLERANT;
- }
- CONTRACTL_END;
-
- ModuleSecurityDescriptorFlags moduleFlags = ModuleSecurityDescriptorFlags_None;
- bool fShouldBeOpportunisticallyCritical = true;
-
-#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
- if (tokenFlags & TokenSecurityDescriptorFlags_APTCA)
- {
- moduleFlags |= ModuleSecurityDescriptorFlags_IsAPTCA;
- }
-#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
-
- if (tokenFlags & TokenSecurityDescriptorFlags_Transparent)
- {
- moduleFlags |= ModuleSecurityDescriptorFlags_IsAllTransparent;
- fShouldBeOpportunisticallyCritical = false;
- }
-
- if (tokenFlags & TokenSecurityDescriptorFlags_Critical)
- {
- fShouldBeOpportunisticallyCritical = false;
-
- // If we're critical, but not all critical that means we're mixed.
- if (tokenFlags & TokenSecurityDescriptorFlags_AllCritical)
- {
- moduleFlags |= ModuleSecurityDescriptorFlags_IsAllCritical;
-
- // If we're all critical and treat as safe, that means we're safe critical
- if (tokenFlags & TokenSecurityDescriptorFlags_TreatAsSafe)
- {
- moduleFlags |= ModuleSecurityDescriptorFlags_IsTreatAsSafe;
- }
- }
- }
-
- // SafeCritical always means Critical + TreatAsSafe; we can get in this case for legacy assemblies if the
- // assembly is actually a v4 assembly which is using the Legacy attribute.
- if (tokenFlags & TokenSecurityDescriptorFlags_SafeCritical)
- {
- moduleFlags |= ModuleSecurityDescriptorFlags_IsAllCritical |
- ModuleSecurityDescriptorFlags_IsTreatAsSafe;
- fShouldBeOpportunisticallyCritical = false;
- }
-
- // If we didn't find an attribute that indicates the assembly cares about transparency, then it is
- // opportunistically critical.
- if (fShouldBeOpportunisticallyCritical)
- {
- _ASSERTE(!(moduleFlags & ModuleSecurityDescriptorFlags_IsAllTransparent));
- _ASSERTE(!(moduleFlags & ModuleSecurityDescriptorFlags_IsAllCritical));
-
- moduleFlags |= ModuleSecurityDescriptorFlags_IsOpportunisticallyCritical;
- }
-
- // If the token asks to not have IL verification done in full trust, propigate that to the module
- if (tokenFlags & TokenSecurityDescriptorFlags_SkipFullTrustVerification)
- {
- moduleFlags |= ModuleSecurityDescriptorFlags_SkipFullTrustVerification;
- }
-
- return moduleFlags;
- }
-
- // Legacy transparency type behavior mappings:
- // Attribute Behavior
- // -----------------------------------------------------
- // Critical (scoped) Critical, but not all critical
- // Critical (all) All critical
- // SafeCritical All safe critical
- // TAS (no critical) No effect on the type, but save TAS bit for members of the type
- // TAS (with scoped critical) SafeCritical, but not all critical
- // TAS (with all critical) All SafeCritical
- virtual TypeSecurityDescriptorFlags MapTypeAttributes(TokenSecurityDescriptorFlags tokenFlags) const
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- SO_INTOLERANT;
- }
- CONTRACTL_END;
-
- TypeSecurityDescriptorFlags typeFlags = TypeSecurityDescriptorFlags_None;
-
- if (tokenFlags & TokenSecurityDescriptorFlags_Critical)
- {
- typeFlags |= TypeSecurityDescriptorFlags_IsCritical;
-
- // We only consider all critical if the critical attribute was present
- if (tokenFlags & TokenSecurityDescriptorFlags_AllCritical)
- {
- typeFlags |= TypeSecurityDescriptorFlags_IsAllCritical;
- }
- }
-
- // SafeCritical always means all critical + TAS
- if (tokenFlags & TokenSecurityDescriptorFlags_SafeCritical)
- {
- typeFlags |= TypeSecurityDescriptorFlags_IsCritical |
- TypeSecurityDescriptorFlags_IsAllCritical |
- TypeSecurityDescriptorFlags_IsTreatAsSafe;
- }
-
- if (tokenFlags & TokenSecurityDescriptorFlags_TreatAsSafe)
- {
- typeFlags |= TypeSecurityDescriptorFlags_IsTreatAsSafe;
- }
-
- return typeFlags;
- }
-};
-
-#endif // !FEATURE_CORECLR
-
//
// Shared transparency behavior objects
//
// static
SecurityTransparencyBehavior *SecurityTransparencyBehavior::s_pStandardTransparencyBehavior = NULL;
-#ifndef FEATURE_CORECLR
-
-// Transpraency behavior object for v2 transparent assemblies
-// static
-SecurityTransparencyBehavior *SecurityTransparencyBehavior::s_pLegacyTransparencyBehavior = NULL;
-
-#endif // !FEATURE_CORECLR
//---------------------------------------------------------------------------------------
//
}
CONTRACT_END;
-#ifndef FEATURE_CORECLR
- if (ruleSet == SecurityRuleSet_Level1)
- {
- // Level 1 rules - v2.0 behavior
- RETURN(GetOrCreateTransparencyBehavior<LegacyTransparencyBehaviorImpl>(&s_pLegacyTransparencyBehavior));
- }
- else
-#endif // FEATURE_CORECLR;
{
// Level 2 rules - v4.0 behavior
RETURN(GetOrCreateTransparencyBehavior<TransparencyBehaviorImpl>(&s_pStandardTransparencyBehavior));
// See the LICENSE file in the project root for more information.
//
-#if defined(FEATURE_CORECLR)
#ifndef SHA1_H_
#define SHA1_H_
};
#endif // SHA1_H_
-#else // !defined(FEATURE_CORECLR)
-#include "crypto/sha1.h"
-#endif // defined(FEATURE_CORECLR)
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
//@CORESYSTODO: what to do?
return E_FAIL;
-#else
-
- HRESULT hr = S_OK; // A result.
- CQuickWSTRBase rName; // Library (scope) or file name.
- int bResize=false; // If true, had to resize the buffer to hold the name.
- LPCWSTR szModule=0; // The module name.
- GUID guid; // A GUID.
- ITypeLib *pITLB=0; // The TypeLib.
- Module *pModule; // The assembly's module.
- WCHAR rcDrive[_MAX_DRIVE]; // Module's drive letter.
- WCHAR rcDir[_MAX_DIR]; // Module's directory.
- WCHAR rcFname[_MAX_FNAME]; // Module's file name.
- USHORT wMajor; // Major version number.
- USHORT wMinor; // Minor version number.
-
- rName.Init();
-
- // Check to see if we have a cached copy.
- pITLB = pAssembly->GetTypeLib();
- if (pITLB)
- {
- // Check to see if the cached value is -1. This indicate that we tried
- // to export the typelib but that the export failed.
- if (pITLB == (ITypeLib*)-1)
- {
- hr = E_FAIL;
- goto ReturnHR;
- }
-
- // We have a cached copy so return it.
- *ppTLB = pITLB;
- hr = S_OK;
- goto ReturnHR;
- }
-
- // Retrieve the name of the module.
- pModule = pAssembly->GetManifestModule();
-
- EX_TRY
- {
- // SString::ConvertToUnicode is THROW_UNLESS_NORMALIZED
- szModule = pModule->GetPath();
- }
- EX_CATCH_HRESULT(hr);
- IfFailGo(hr);
-
- // Retrieve the guid for typelib that would be generated from the assembly.
- IfFailGo(GetTypeLibGuidForAssembly(pAssembly, &guid));
-
- // If the typelib is for the runtime library, we'd better know where it is.
- if (guid == LIBID_ComPlusRuntime)
- {
- ULONG dwSize = (ULONG)rName.MaxSize();
- while (FAILED(GetInternalSystemDirectory(rName.Ptr(), &dwSize)))
- {
- IfFailGo(rName.ReSizeNoThrow(dwSize=(ULONG)rName.MaxSize()*2));
- }
-
- IfFailGo(rName.ReSizeNoThrow(dwSize + wcslen(g_pwBaseLibraryTLB) + 3));
- wcscat_s(rName.Ptr(), rName.Size(), g_pwBaseLibraryTLB);
- hr = LoadTypeLibExWithFlags(rName.Ptr(), flags, &pITLB);
- goto ErrExit;
- }
-
- // Retrieve the major and minor version number.
- IfFailGo(GetTypeLibVersionForAssembly(pAssembly, &wMajor, &wMinor));
-
- // Maybe the module was imported from COM, and we can get the libid of the existing typelib.
- if (pAssembly->IsImportedFromTypeLib())
- {
- hr = LoadRegTypeLibWithFlags(guid, wMajor, wMinor, flags, &pITLB);
- if (SUCCEEDED(hr))
- goto ErrExit;
-
- // Try just the Assembly version
- pAssembly->GetVersion(&wMajor, &wMinor, NULL, NULL);
- hr = LoadRegTypeLibWithFlags(guid, wMajor, wMinor, flags, &pITLB);
- if (SUCCEEDED(hr))
- goto ErrExit;
-
- // Try loading the highest registered version.
- hr = LoadRegTypeLibWithFlags(guid, -1, -1, flags, &pITLB);
- if (SUCCEEDED(hr))
- goto ErrExit;
-
- // The module is known to be imported, so no need to try conversion.
-
- // Set the error info for most callers.
- VMPostError(TLBX_E_CIRCULAR_EXPORT2, szModule);
-
- // Set the hr for the case where we're trying to load a type library to
- // resolve a type reference from another library. The error message will
- // be posted where more information is available.
- if (hr == TYPE_E_LIBNOTREGISTERED)
- hr = TLBX_W_LIBNOTREGISTERED;
- else
- hr = TLBX_E_CANTLOADLIBRARY;
-
- IfFailGo(hr);
- }
-
- // Try to load the registered typelib.
- hr = LoadRegTypeLibWithFlags(guid, wMajor, wMinor, flags, &pITLB);
- if(hr == S_OK)
- goto ErrExit;
-
- // Try just the Assembly version
- pAssembly->GetVersion(&wMajor, &wMinor, NULL, NULL);
- hr = LoadRegTypeLibWithFlags(guid, wMajor, wMinor, flags, &pITLB);
- if (SUCCEEDED(hr))
- goto ErrExit;
-
- // If that fails, try loading the highest registered version.
- hr = LoadRegTypeLibWithFlags(guid, -1, -1, flags, &pITLB);
- if(hr == S_OK)
- goto ErrExit;
-
- // If caller only wants registered typelibs, exit now, with error from prior call.
- if (flags & TlbExporter_OnlyReferenceRegistered)
- goto ErrExit;
-
- // If we haven't managed to find the typelib so far try and load the typelib by name.
- hr = LoadTypeLibExWithFlags(szModule, flags, &pITLB);
- if(hr == S_OK)
- {
- // Check libid.
- TLIBATTR *pTlibAttr;
- int bMatch;
-
- IfFailGo(pITLB->GetLibAttr(&pTlibAttr));
- bMatch = pTlibAttr->guid == guid;
- pITLB->ReleaseTLibAttr(pTlibAttr);
-
- if (bMatch)
- {
- goto ErrExit;
- }
- else
- {
- SafeReleasePreemp(pITLB);
- pITLB = NULL;
- hr = TLBX_E_CANTLOADLIBRARY;
- }
- }
-
- // Add a ".tlb" extension and try again.
- IfFailGo(rName.ReSizeNoThrow((int)(wcslen(szModule) + 5)));
- // Check if szModule already has an extension.
- LPCWSTR ext;
- size_t extSize;
- SplitPathInterior(szModule, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, &ext, &extSize);
- if (ext != nullptr)
- {
- // szModule already has an extension. Make a copy without the extension.
- wcsncpy_s(rName.Ptr(), rName.Size(), szModule, ext - szModule);
- }
- else
- {
- // szModule does not have an extension. Copy the whole string.
- wcscpy_s(rName.Ptr(), rName.Size(), szModule);
- }
- wcscat_s(rName.Ptr(), rName.Size(), W(".tlb"));
-
- hr = LoadTypeLibExWithFlags(rName.Ptr(), flags, &pITLB);
- if(hr == S_OK)
- {
- // Check libid.
- TLIBATTR *pTlibAttr;
- int bMatch;
- IfFailGo(pITLB->GetLibAttr(&pTlibAttr));
- bMatch = pTlibAttr->guid == guid;
- pITLB->ReleaseTLibAttr(pTlibAttr);
- if (bMatch)
- {
- goto ErrExit;
- }
- else
- {
- SafeReleasePreemp(pITLB);
- pITLB = NULL;
- hr = TLBX_E_CANTLOADLIBRARY;
- }
- }
-
- // If the auto create flag is set then try and export the typelib from the module.
- if (bAutoCreate)
- {
- // Try to export the typelib right now.
- // This is FTL export (Fractionally Too Late).
- hr = ExportTypeLibFromLoadedAssemblyNoThrow(pAssembly, 0, &pITLB, 0, flags);
- if (FAILED(hr))
- {
- // If the export failed then remember it failed by setting the typelib
- // to -1 on the assembly.
- pAssembly->SetTypeLib((ITypeLib *)-1);
- IfFailGo(hr);
- }
- }
-
-ErrExit:
- // If we successfully opened (or created) the typelib, cache a pointer, and return it to caller.
- if (pITLB)
- {
- pAssembly->SetTypeLib(pITLB);
- *ppTLB = pITLB;
- }
-ReturnHR:
- rName.Destroy();
- return hr;
-#endif //FEATURE_CORECLR
} // HRESULT GetITypeLibForAssembly()
// In case of APPX process we always use the standard marshaller.
// In Non-APPX process use standard marshalling for everything except in-proc servers.
// In case of CoreCLR, we always use the standard marshaller as well.
-#if !defined(FEATURE_CORECLR)
- if (!AppX::IsAppXProcess() && (dwDestContext == MSHCTX_INPROC))
- {
- *ppMarshalRet = NULL;
- return S_OK;
- }
-#endif // !FEATURE_CORECLR
SafeComHolderPreemp<IUnknown> pMarshalerObj = NULL;
IfFailRet(CoCreateFreeThreadedMarshaler(NULL, &pMarshalerObj));
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
_ASSERTE(!"NYI");
return E_NOTIMPL;
-#else // FEATURE_CORECLR
-
- HRESULT hr = S_OK;
- if (pBStr == NULL)
- return E_POINTER;
-
- *pBStr = NULL;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr)
- {
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
-
- SimpleComCallWrapper *pSimpleWrap = SimpleComCallWrapper::GetWrapperFromIP( pManaged );
- ComCallWrapper *pComCallWrap = pSimpleWrap->GetMainWrapper();
-
- _ASSERTE(pComCallWrap != NULL);
-
- //@todo don't allow serialization of Configured objects through DCOM
- _ASSERTE(GetThread()->GetDomain()->GetId() == pSimpleWrap->GetDomainID());
-
- BOOL fLegacyMode = (GetAppDomain()->GetComOrRemotingFlag() == COMorRemoting_LegacyMode);
-
- OBJECTREF oref = pComCallWrap->GetObjectRef();
- GCPROTECT_BEGIN(oref)
- {
- // GetSerializedBuffer is only called in cross-runtime/cross-process scenarios so we pass
- // fCrossRuntime=TRUE unless we are in legacy mode
- if (!ConvertObjectToBSTR(&oref, !fLegacyMode, pBStr))
- {
- // ConvertObjectToBSTR returning FALSE is equivalent to throwing SerializationException
- hr = COR_E_SERIALIZATION;
- }
- }
- GCPROTECT_END();
- }
- END_EXTERNAL_ENTRYPOINT;
-
- return hr;
-
-#endif // FEATURE_CORECLR
}
//------------------------------------------------------------------------------------------
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
-#ifdef _TARGET_X86_
- // m_pInterceptStub is either NULL if we never called on this method, -1 if we're not
- // hosted, or the host hook stub if we are hosted. The stub will extract the real target
- // from the 'this' argument.
- PVOID pInterceptStub = VolatileLoadWithoutBarrier(&pComInfo->m_pInterceptStub);
-
- if (pInterceptStub != (LPVOID)-1)
- {
- if (pInterceptStub != NULL)
- {
- return pInterceptStub;
- }
-
- if (NDirect::IsHostHookEnabled() || pComInfo->HasCopyCtorArgs())
- {
- return NULL;
- }
-
- if (!EnsureWritablePagesNoThrow(&pComInfo->m_pInterceptStub, sizeof(pComInfo->m_pInterceptStub)))
- {
- return NULL;
- }
-
- pComInfo->m_pInterceptStub = (LPVOID)-1;
- }
-#else // _TARGET_X86_
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (NDirect::IsHostHookEnabled())
- {
- // There's one static stub on !_TARGET_X86_.
- return (LPVOID)GetEEFuncEntryPoint(PInvokeStubForHost);
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-#endif // _TARGET_X86_
-#endif // FEATURE_CORECLR
LPVOID *lpVtbl = *(LPVOID **)pUnk;
return lpVtbl[pComInfo->m_cachedComSlot];
pRetUnk.Release();
}
-#ifndef FEATURE_CORECLR
-#ifdef _TARGET_X86_
- GCX_PREEMP();
- Stub *pInterceptStub = NULL;
-
- if (pComInfo->m_pInterceptStub == NULL)
- {
- if (pComInfo->HasCopyCtorArgs())
- {
- // static stub that gets its arguments in a thread-static field
- pInterceptStub = NDirect::GetStubForCopyCtor();
- }
-
- if (NDirect::IsHostHookEnabled())
- {
- pInterceptStub = pComInfo->GenerateStubForHost(
- pMD->GetDomain()->GetLoaderAllocator()->GetStubHeap(),
- pInterceptStub);
- }
-
- EnsureWritablePages(&pComInfo->m_pInterceptStub);
-
- if (pInterceptStub != NULL)
- {
- if (InterlockedCompareExchangeT(&pComInfo->m_pInterceptStub,
- (LPVOID)pInterceptStub->GetEntryPoint(),
- NULL) != NULL)
- {
- pInterceptStub->DecRef();
- }
- }
- else
- {
- pComInfo->m_pInterceptStub = (LPVOID)-1;
- }
- }
-#endif // _TARGET_X86_
-#endif // !FEATURE_CORECLR
*ppTarget = GetCOMIPFromRCW_GetTarget(pRetUnk, pComInfo);
_ASSERTE(*ppTarget != NULL);
}
FCIMPLEND
-#ifndef FEATURE_CORECLR // CAS
-static void DoDeclarativeActionsForPInvoke(MethodDesc* pCurrent)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- SO_INTOLERANT;
- }
- CONTRACTL_END;
-
- MethodSecurityDescriptor MDSecDesc(pCurrent);
- MethodSecurityDescriptor::LookupOrCreateMethodSecurityDescriptor(&MDSecDesc);
-
- DeclActionInfo* pRuntimeDeclActionInfo = MDSecDesc.GetRuntimeDeclActionInfo();
- if (pRuntimeDeclActionInfo != NULL)
- {
- // Tell the debugger not to start on any managed code that we call in this method
- FrameWithCookie<DebuggerSecurityCodeMarkFrame> __dbgSecFrame;
-
- Security::DoDeclarativeActions(pCurrent, pRuntimeDeclActionInfo, NULL, &MDSecDesc);
-
- // Pop the debugger frame
- __dbgSecFrame.Pop();
- }
-}
-#endif // FEATURE_CORECLR
-
-#ifndef FEATURE_CORECLR
-#ifndef _WIN64
-FCIMPL3(void*, StubHelpers::GetFinalStubTarget, LPVOID pStubArg, LPVOID pUnmngThis, DWORD dwFlags)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(SF_IsForwardStub(dwFlags));
- }
- CONTRACTL_END;
-
- if (SF_IsCALLIStub(dwFlags))
- {
- // stub argument is the target
- return pStubArg;
- }
- else if (SF_IsDelegateStub(dwFlags))
- {
- // stub argument is not used but we pass _methodPtrAux which is the target
- return pStubArg;
- }
- else if (SF_IsCOMStub(dwFlags))
- {
- // stub argument is a ComPlusCallMethodDesc
- ComPlusCallMethodDesc *pCMD = (ComPlusCallMethodDesc *)pStubArg;
- LPVOID *lpVtbl = *(LPVOID **)pUnmngThis;
- return lpVtbl[pCMD->m_pComPlusCallInfo->m_cachedComSlot];
- }
- else // P/Invoke
- {
- // secret stub argument is an NDirectMethodDesc
- NDirectMethodDesc *pNMD = (NDirectMethodDesc *)pStubArg;
- return pNMD->GetNativeNDirectTarget();
- }
-}
-FCIMPLEND
-#endif // !_WIN64
-
-FCIMPL1(void, StubHelpers::DemandPermission, NDirectMethodDesc *pNMD)
-{
- FCALL_CONTRACT;
- // ETWOnStartup (SecurityCatchCall, SecurityCatchCallEnd); // this is messing up HMF below
-
- if (pNMD != NULL)
- {
- g_IBCLogger.LogMethodDescAccess(pNMD);
-
- if (pNMD->IsInterceptedForDeclSecurity())
- {
- if (pNMD->IsInterceptedForDeclSecurityCASDemandsOnly() &&
- SecurityStackWalk::HasFlagsOrFullyTrusted(1 << SECURITY_UNMANAGED_CODE))
- {
- // Track perfmon counters. Runtime security checks.
- Security::IncrementSecurityPerfCounter();
- }
- else
- {
- HELPER_METHOD_FRAME_BEGIN_0();
- DoDeclarativeActionsForPInvoke(pNMD);
- HELPER_METHOD_FRAME_END();
- }
- }
- }
- else
- {
- // This is either CLR->COM or delegate P/Invoke (we don't call this helper for CALLI).
- HELPER_METHOD_FRAME_BEGIN_0();
- SecurityStackWalk::SpecialDemand(SSWT_DECLARATIVE_DEMAND, SECURITY_UNMANAGED_CODE);
- HELPER_METHOD_FRAME_END();
- }
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
FCIMPL2(void, StubHelpers::ThrowInteropParamException, UINT resID, UINT paramIdx)
{
static FCDECL1(void*, GetNDirectTarget, NDirectMethodDesc* pNMD);
static FCDECL2(void*, GetDelegateTarget, DelegateObject *pThisUNSAFE, UINT_PTR *ppStubArg);
-#ifndef FEATURE_CORECLR
-#ifndef _WIN64
- static FCDECL3(void*, GetFinalStubTarget, LPVOID pStubArg, LPVOID pUnmngThis, DWORD dwFlags);
-#endif // !_WIN64
- static FCDECL1(void, DemandPermission, NDirectMethodDesc *pNMD);
-#endif // !FEATURE_CORECLR
static FCDECL2(void, ThrowInteropParamException, UINT resID, UINT paramIdx);
static FCDECL1(Object*, GetHRExceptionObject, HRESULT hr);
COUNTER_ONLY(GetPerfCounters().m_LocksAndThreads.cContention++);
-#ifndef FEATURE_CORECLR
- // Fire a contention start event for a managed contention
- FireEtwContentionStart_V1(ETW::ContentionLog::ContentionStructs::ManagedContention, GetClrInstanceId());
-#endif // !FEATURE_CORECLR
LogContention();
Thread *pCurThread = GetThread();
Enter();
bEntered = TRUE;
}
-#ifndef FEATURE_CORECLR
- FireEtwContentionStop(ETW::ContentionLog::ContentionStructs::ManagedContention, GetClrInstanceId());
-#endif // !FEATURE_CORECLR
return bEntered;
}
if (!CPUGroupInfo::CanEnableGCCPUGroups() || !CPUGroupInfo::CanEnableThreadUseAllCpuGroups())
return;
-#ifndef FEATURE_CORECLR
- // We only handle the non-hosted case here. If CLR is hosted, the hosting
- // process controls the physical OS Threads. If CLR is not hosted, we can
- // set thread group affinity on OS threads directly.
- HostComHolder<IHostTask> pHostTask (GetHostTaskWithAddRef());
- if (pHostTask != NULL)
- return;
-#endif //!FEATURE_CORECLR
//Borrow the ThreadStore Lock here: Lock ThreadStore before distributing threads
ThreadStoreLockHolder TSLockHolder(TRUE);
if (!CPUGroupInfo::CanEnableGCCPUGroups() || !CPUGroupInfo::CanEnableThreadUseAllCpuGroups())
return;
-#ifndef FEATURE_CORECLR
- // We only handle the non-hosted case here. If CLR is hosted, the hosting
- // process controls the physical OS Threads. If CLR is not hosted, we can
- // set thread group affinity on OS threads directly.
- HostComHolder<IHostTask> pHostTask (GetHostTaskWithAddRef());
- if (pHostTask != NULL)
- return;
-#endif //!FEATURE_CORECLR
ThreadStoreLockHolder TSLockHolder(TRUE);
m_dwLockCount = 0;
m_dwBeginLockCount = 0;
-#ifndef FEATURE_CORECLR
- m_dwBeginCriticalRegionCount = 0;
- m_dwCriticalRegionCount = 0;
- m_dwThreadAffinityCount = 0;
-#endif // !FEATURE_CORECLR
#ifdef _DEBUG
dbg_m_cSuspendedThreads = 0;
return hThread;
}
-#ifndef FEATURE_CORECLR
-/*
- The following are copied from MSDN:
- http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/thread_stack_size.asp
-
- To change the initially committed stack space, use the dwStackSize parameter of the CreateThread,
- CreateRemoteThread, or CreateFiber function. This value is rounded up to the nearest page.
- Generally, the reserve size is the default reserve size specified in the executable header.
- However, if the initially committed size specified by dwStackSize is larger than the default reserve size,
- the reserve size is this new commit size rounded up to the nearest multiple of 1 MB.
-
- To change the reserved stack size, set the dwCreationFlags parameter of CreateThread or CreateRemoteThread
- to STACK_SIZE_PARAM_IS_A_RESERVATION and use the dwStackSize parameter. In this case, the initially
- committed size is the default size specified in the executable header.
-
-*/
-BOOL Thread::CheckThreadStackSize(SIZE_T *pSizeToCommitOrReserve,
- BOOL isSizeToReserve // When TRUE, the previous argument is the stack size to reserve.
- // Otherwise, it is the size to commit.
- )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- //g_SystemInfo is global pointer to SYSTEM_INFO struct
- SIZE_T dwAllocSize = (SIZE_T)g_SystemInfo.dwAllocationGranularity;
- SIZE_T dwPageSize = (SIZE_T)g_SystemInfo.dwPageSize;
-
- //Don't want users creating threads
- // with a stackSize request < 256K
- //This value may change up or down as we see fit so don't doc to user
- //
- if(isSizeToReserve && 0x40000 > (*pSizeToCommitOrReserve))
- {
- *pSizeToCommitOrReserve = 0x40000;
- }
-
- *pSizeToCommitOrReserve = ALIGN(*pSizeToCommitOrReserve, dwAllocSize);
-
- //
- // Let's get the stack sizes from the PE file that started process.
- //
- SIZE_T ExeSizeOfStackReserve = 0;
- SIZE_T ExeSizeOfStackCommit = 0;
-
- if (!GetProcessDefaultStackSize(&ExeSizeOfStackReserve, &ExeSizeOfStackCommit))
- return FALSE;
-
- // Now let's decide which sizes OS are going to use.
- SIZE_T sizeToReserve = 0;
- SIZE_T sizeToCommit = 0;
-
- if (isSizeToReserve) {
- // The passed-in *pSizeToCommitOrReserve is the stack size to reserve.
- sizeToReserve = *pSizeToCommitOrReserve;
- // OS will use ExeSizeOfStackCommit as the commited size.
- sizeToCommit = ExeSizeOfStackCommit;
- }
- else {
- // The passed-in *pSizeToCommitOrReserve is the stack size to commit.
- sizeToCommit = *pSizeToCommitOrReserve;
- // OS will use ExeSizeOfStackReserve as the reserved size.
- sizeToReserve = ExeSizeOfStackReserve;
-
- // However, if the initially committed size specified by dwStackSize is larger than
- // the default reserve size, the reserve size is this new commit size rounded up to
- // the nearest multiple of 1 MB.
- if (sizeToCommit > ExeSizeOfStackReserve) {
- sizeToReserve = ALIGN(sizeToCommit, 0x1000000);
- }
-
- if (!g_pConfig->GetDisableCommitThreadStack())
- {
- // We will commit the full stack when a thread starts. But if the PageFile is full, we may hit
- // stack overflow at random places during startup.
- // Therefore if we are unlikely to obtain space from PageFile, we will fail creation of a thread.
-
- *pSizeToCommitOrReserve = sizeToReserve - HARD_GUARD_REGION_SIZE;
-
- // OS's behavior is not consistent on if guard page is marked when we ask OS to commit the stack
- // up to 2nd to last page.
- // On Win2k3, the 2nd to last page is marked with guard bit.
- // On WinXP, the 2nd to last page is not marked with guard bit.
- // To be safe, we will not commit the 2nd to last page.
- *pSizeToCommitOrReserve -= HARD_GUARD_REGION_SIZE;
- // To make it more interesting, on X64, if we request to commit stack except the last two pages,
- // OS commit the whole stack, and mark the last two pages as guard page.
- *pSizeToCommitOrReserve -= 2*HARD_GUARD_REGION_SIZE;
- }
- }
-
- // Ok, we now know what sizes OS will use to create the thread.
- // Check to see if we have the room for guard pages.
- return ThreadWillCreateGuardPage(sizeToReserve, sizeToCommit);
-}
-#endif // FEATURE_CORECLR
BOOL Thread::GetProcessDefaultStackSize(SIZE_T* reserveSize, SIZE_T* commitSize)
{
HANDLE h = NULL;
DWORD dwCreationFlags = CREATE_SUSPENDED;
-#ifdef FEATURE_CORECLR
dwCreationFlags |= STACK_SIZE_PARAM_IS_A_RESERVATION;
#ifndef FEATURE_PAL // the PAL does its own adjustments as necessary
sizeToCommitOrReserve = OS_PAGE_SIZE + 1;
}
#endif // !FEATURE_PAL
-#else
- if(sizeToCommitOrReserve != 0)
- {
- dwCreationFlags |= STACK_SIZE_PARAM_IS_A_RESERVATION;
-
- //
- // In this case we also force CommitThreadStack to commit the whole stack, even if we're configured not to do so.
- // The config value is used to reduce the resource usage for default stack allocations; for non-default allocations,
- // we assume the user has given us the correct size (and they're really going to need it). This way we don't
- // need to offer a Thread constructor that takes a confusing "stack size param is a commit size" parameter.
- //
- SetThreadStateNC(TSNC_ForceStackCommit);
- }
-
- // Check that we will have (reserved and never committed) guard pages at the end of the stack.
- // If this call returns false then it will lead to an OOM exception on return.
- // This is reasonable since a large stack was requested and we couldn't get it.
- if(!CheckThreadStackSize(&sizeToCommitOrReserve,
- (sizeToCommitOrReserve != 0)))
- {
- return FALSE;
- }
-#endif
intermediateThreadParam* lpThreadArgs = new (nothrow) intermediateThreadParam;
if (lpThreadArgs == NULL)
// So on CoreCLR (where FEATURE_COMINTEROP is not currently defined) we can actually reach this point.
// We can't fix this, because it's a breaking change, so we just won't assert here.
// The result is that WaitAll on an STA thread in CoreCLR will behave stragely, as described above.
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
- else
- _ASSERTE(!"WaitAll in an STA with more than one handle will deadlock");
-#endif
}
if (bWaitAll)
BOOL Thread::CommitThreadStack(Thread* pThreadOptional)
{
-#ifndef FEATURE_CORECLR
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- if (FAILED(CLRSetThreadStackGuarantee(STSGuarantee_Force)))
- return FALSE;
-
- if (g_pConfig->GetDisableCommitThreadStack() && (pThreadOptional == NULL || !pThreadOptional->HasThreadStateNC(TSNC_ForceStackCommit)))
- return TRUE;
-
-
- // This is a temporary fix for VSWhidbey 259155. In CommitThreadStack() we determine the bounds of the
- // region between the guard page and the hard guard region for a thread's stack and then commit that
- // region. Sometimes we cross a page boundary while calculating the bounds or doing the commit (in
- // VirtualQuery or VirtualAlloc), such that the guard page is moved after we've already gotten it's
- // location. When that happens we commit too many pages and destroy the guard page. To fix this we
- // do a small stack allocation that ensures that we have enough stack space for all of the
- // CommitThreadStack() work
-
- AllocateSomeStack();
-
- // Grab the info about the first region of the stack. First, we grab the region where we are now (&tmpMBI),
- // then we use the allocation base of that to grab the first region.
- MEMORY_BASIC_INFORMATION tmpMBI;
- SIZE_T dwRes;
-
- dwRes = ClrVirtualQuery((const void *)&tmpMBI, &tmpMBI, sizeof(MEMORY_BASIC_INFORMATION));
-
- if (sizeof(MEMORY_BASIC_INFORMATION) != dwRes)
- {
- return FALSE;
- }
-
- dwRes = ClrVirtualQuery((const void *)((BYTE*)tmpMBI.AllocationBase + HARD_GUARD_REGION_SIZE), &tmpMBI, sizeof(MEMORY_BASIC_INFORMATION));
-
- if (sizeof(MEMORY_BASIC_INFORMATION) != dwRes)
- {
- return FALSE;
- }
-
- // We commit the reserved part of the stack, if necessary, minus one page for the "hard" guard page.
- if (tmpMBI.State == MEM_RESERVE)
- {
- // Note: we leave the "hard" guard region uncommitted.
- void *base = (BYTE*)tmpMBI.AllocationBase + HARD_GUARD_REGION_SIZE;
-
- // We are committing a page on stack. If we call host for this operation,
- // host needs to avoid adding it to the memory consumption. Therefore
- // we call into OS directly.
-#undef VirtualAlloc
- void *p = VirtualAlloc(base,
- tmpMBI.RegionSize,
- MEM_COMMIT,
- PAGE_READWRITE);
-#define VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect) \
- Dont_Use_VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect)
-
- if (p != base )
- {
- DWORD err = GetLastError();
- STRESS_LOG2(LF_EH, LL_ALWAYS,
- "Thread::CommitThreadStack: failed to commit stack for TID 0x%x with error 0x%x\n",
- ::GetCurrentThreadId(), err);
-
- return FALSE;
- }
- }
-
- INDEBUG(DebugLogStackMBIs());
-
-#endif
return TRUE;
}
{
pFrame->SetLockCount(m_dwBeginLockCount);
m_dwBeginLockCount = m_dwLockCount;
-#ifndef FEATURE_CORECLR
- pFrame->SetCriticalRegionCount(m_dwBeginCriticalRegionCount);
- m_dwBeginCriticalRegionCount = m_dwCriticalRegionCount;
-#endif // !FEATURE_CORECLR
}
if (m_Context == pContext) {
PushDomain(pDomain->GetId());
STRESS_LOG1(LF_APPDOMAIN, LL_INFO100000, "Entering into ADID=%d\n", pDomain->GetId().m_dwId);
-#ifndef FEATURE_CORECLR
- //
- // Push execution contexts (that could contain call context) into frame to avoid leaks
- //
-
- if (IsExposedObjectSet())
- {
- THREADBASEREF ref = (THREADBASEREF) ObjectFromHandle(m_ExposedObject);
- _ASSERTE(ref != NULL);
- if (ref->GetExecutionContext() != NULL)
- {
- pFrame->SetReturnExecutionContext(ref->GetExecutionContext());
- ref->SetExecutionContext(NULL);
- }
- }
-#endif //!FEATURE_CORECLR
//
// Store the last thrown object in the ContextTransitionFrame before we null it out
m_dwLockCount = m_dwBeginLockCount;
m_dwBeginLockCount = pFrame->GetLockCount();
-#ifndef FEATURE_CORECLR
- m_dwCriticalRegionCount = m_dwBeginCriticalRegionCount;
- m_dwBeginCriticalRegionCount = pFrame->GetCriticalRegionCount();
-#endif // !FEATURE_CORECLR
}
if (fChangedDomains)
{
-#ifndef FEATURE_CORECLR
- //
- // Pop execution contexts (could contain call context) from frame if applicable
- //
-
- if (IsExposedObjectSet())
- {
- THREADBASEREF ref = (THREADBASEREF) ObjectFromHandle(m_ExposedObject);
- _ASSERTE(ref != NULL);
- ref->SetExecutionContext(pFrame->GetReturnExecutionContext());
- }
-#endif //!FEATURE_CORECLR
// Do this last so that thread is not labeled as out of the domain until all cleanup is done.
ADID adid=pCurrentDomain->GetId();
// Ensure that IP for WatsonBucketing has been collected if the exception is preallocated.
#ifdef _DEBUG
-#ifdef FEATURE_CORECLR
// On CoreCLR, Watson may not be enabled. Thus, we should
// skip this.
if (IsWatsonEnabled())
-#endif // FEATURE_CORECLR
{
if (CLRException::IsPreallocatedExceptionObject(CLRException::GetThrowableFromException(pEx)))
{
switch (kind)
{
case kLastException:
-#ifdef FEATURE_CORECLR
gc.pMarshaledThrowable = gc.orBlob;
-#else
- AppDomainHelper::UnmarshalObject(GetAppDomain(), &gc.orBlob, &gc.pMarshaledThrowable);
-#endif //FEATURE_CORECLR
break;
case kOutOfMemoryException:
{
_ASSERTE(flags == MTCSF_NormalBase);
-#ifdef FEATURE_CORECLR
if(!IsSingleAppDomain())
{
// This assert shouldnt be hit in CoreCLR since:
// So, if this is hit, something is not right!
_ASSERTE(!"How come a managed thread in CoreCLR has suffered unhandled exception in DefaultDomain?");
}
-#endif // FEATURE_CORECLR
LOG((LF_EH, LL_INFO100, "ThreadBaseRedirectingFilter: setting TSNC_ProcessedUnhandledException\n"));
-#if defined(FEATURE_CORECLR)
//
// In the default domain, when an exception goes unhandled on a managed thread whose threadbase is in the VM (e.g. explicitly spawned threads,
// ThreadPool threads, finalizer thread, etc), CLR can end up in the unhandled exception processing path twice.
// will fail to honor the host policy (e.g. swallow unhandled exception). Thus, the 2nd unhandled exception may end up crashing the app when it should not.
//
if (IsSingleAppDomain() && (ret != EXCEPTION_EXECUTE_HANDLER))
-#endif // defined(FEATURE_CORECLR)
{
// Since we have already done unhandled exception processing for it, we dont want it
// to happen again if our UEF gets invoked upon returning back to the OS.
TryParam *pTryParam;
Thread *pThread;
-#ifdef FEATURE_CORECLR
BOOL *pfHadException;
-#endif // FEATURE_CORECLR
#ifdef WIN64EXCEPTIONS
Frame *pFrame;
args.pTryParam = ¶m;
args.pThread = pThread;
-#ifdef FEATURE_CORECLR
BOOL fHadException = TRUE;
args.pfHadException = &fHadException;
-#endif // FEATURE_CORECLR
#ifdef WIN64EXCEPTIONS
args.pFrame = pFrame;
}
PAL_ENDTRY;
-#ifdef FEATURE_CORECLR
*(pArgs->pfHadException) = FALSE;
-#endif // FEATURE_CORECLR
}
PAL_FINALLY
{
-#ifdef FEATURE_CORECLR
// If we had a breakpoint exception that has gone unhandled,
// then switch to the correct AD context. Its fine to do this
// here because:
{
ReturnToPreviousAppDomain();
}
-#endif // FEATURE_CORECLR
catchFrame.Pop();
}
PAL_ENDTRY;
FullResetThread();
}
-#ifndef FEATURE_CORECLR
- _ASSERTE (m_dwCriticalRegionCount == 0);
- m_dwCriticalRegionCount = 0;
-
- _ASSERTE (m_dwThreadAffinityCount == 0);
- m_dwThreadAffinityCount = 0;
-#endif // !FEATURE_CORECLR
//m_MarshalAlloc.Collapse(NULL);
ResetThreadStateNC(TSNC_UnbalancedLocks);
m_dwLockCount = 0;
-#ifndef FEATURE_CORECLR
- m_dwCriticalRegionCount = 0;
-#endif // !FEATURE_CORECLR
InternalSwitchOut();
m_OSThreadId = SWITCHED_OUT_FIBER_OSID;
LIMITED_METHOD_CONTRACT;
*pLockCount = m_dwLockCount;
-#ifndef FEATURE_CORECLR
- *pLockCount += m_dwCriticalRegionCount;
-#endif // !FEATURE_CORECLR
return S_OK;
}
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- if (!CLRTaskHosted())
- {
- return;
- }
-
- if (IsGCSpecialThread() || IsDbgHelperSpecialThread())
- {
- return;
- }
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTaskManager *pManager = CorHost2::GetHostTaskManager();
-
- HRESULT hr;
-
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pManager->BeginThreadAffinity();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- _ASSERTE (hr == S_OK);
- Thread *pThread = GetThread();
-
- if (pThread)
- {
- pThread->IncThreadAffinityCount();
-#ifdef _DEBUG
- pThread->AddFiberInfo(Thread::ThreadTrackInfo_Affinity);
-#endif
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-#endif // !FEATURE_CORECLR
}
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- if (!CLRTaskHosted())
- {
- return;
- }
-
- if (IsGCSpecialThread() || IsDbgHelperSpecialThread())
- {
- return;
- }
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTaskManager *pManager = CorHost2::GetHostTaskManager();
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- Thread *pThread = GetThread();
- if (pThread)
- {
- pThread->DecThreadAffinityCount ();
-#ifdef _DEBUG
- pThread->AddFiberInfo(Thread::ThreadTrackInfo_Affinity);
-#endif
- }
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- HRESULT hr = S_OK;
-
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pManager->EndThreadAffinity();
- END_SO_TOLERANT_CODE_CALLING_HOST;
-
- _ASSERTE (hr == S_OK);
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-#endif // !FEATURE_CORECLR
}
void Thread::SetupThreadForHost()
#endif
//***************************************************************************
-#if defined(_DEBUG) && defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
- #define HAS_TRACK_CXX_EXCEPTION_CODE_HACK 1
- #define TRACK_CXX_EXCEPTION_CODE_HACK
-#else
#define HAS_TRACK_CXX_EXCEPTION_CODE_HACK 0
-#endif
// manifest constant for waiting in the exposed classlibs
const INT32 INFINITE_TIMEOUT = -1;
// in the object header to store it.
DWORD m_ThreadId;
- #if HAS_TRACK_CXX_EXCEPTION_CODE_HACK // do we have C++ exception code tracking?
- // It's very hard to deal with SEH properly using C++ catch handlers. The
- // following field is updated with the correct SEH exception whenever a C++
- // __CxxFrameHandler3 call is made on this thread. If you grab it at the
- // top of a C++ catch(...), it's likely to be correct.
- DWORD m_LastCxxSEHExceptionCode;
- #endif // HAS_TRACK_CXX_EXCEPTION_CODE_HACK
// RWLock state
LockEntry *m_pHead;
private:
DWORD m_dwBeginLockCount; // lock count when the thread enters current domain
-#ifndef FEATURE_CORECLR
- DWORD m_dwBeginCriticalRegionCount; // lock count when the thread enters current domain
- DWORD m_dwCriticalRegionCount;
-
- DWORD m_dwThreadAffinityCount;
-#endif // !FEATURE_CORECLR
#ifdef _DEBUG
DWORD dbg_m_cSuspendedThreads;
LIMITED_METHOD_CONTRACT;
_ASSERTE(m_dwLockCount >= m_dwBeginLockCount);
-#ifndef FEATURE_CORECLR
- _ASSERTE(m_dwCriticalRegionCount >= m_dwBeginCriticalRegionCount);
-#endif // !FEATURE_CORECLR
// Equivalent to (m_dwLockCount != m_dwBeginLockCount ||
// m_dwCriticalRegionCount ! m_dwBeginCriticalRegionCount),
// but without branching instructions
BOOL fHasLock = (m_dwLockCount ^ m_dwBeginLockCount);
-#ifndef FEATURE_CORECLR
- fHasLock |= (m_dwCriticalRegionCount ^ m_dwBeginCriticalRegionCount);
-#endif // !FEATURE_CORECLR
return fHasLock;
}
-#ifndef FEATURE_CORECLR
- inline void BeginCriticalRegion()
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE (GetThread() == this);
- if (CLRHosted())
- {
- m_dwCriticalRegionCount ++;
- _ASSERTE (m_dwCriticalRegionCount != 0);
- }
- }
-
- inline void EndCriticalRegion()
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE (GetThread() == this);
- if (CLRHosted())
- {
- _ASSERTE (m_dwCriticalRegionCount > 0);
- m_dwCriticalRegionCount --;
- }
- }
-
- inline void BeginCriticalRegion_NoCheck()
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE (GetThread() == this);
- m_dwCriticalRegionCount ++;
- _ASSERTE (m_dwCriticalRegionCount != 0);
- }
-
- inline void EndCriticalRegion_NoCheck()
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE (GetThread() == this);
- _ASSERTE (m_dwCriticalRegionCount > 0);
- m_dwCriticalRegionCount --;
- }
-#endif // !FEATURE_CORECLR
inline BOOL HasCriticalRegion()
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- return m_dwCriticalRegionCount != 0;
-#else
return FALSE;
-#endif
}
inline DWORD GetNewHashCode()
static void BeginThreadAffinity();
static void EndThreadAffinity();
-#ifndef FEATURE_CORECLR
- inline void IncThreadAffinityCount()
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE (GetThread() == this);
- m_dwThreadAffinityCount++;
- _ASSERTE (m_dwThreadAffinityCount > 0);
- }
- inline void DecThreadAffinityCount()
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE (GetThread() == this);
- _ASSERTE (m_dwThreadAffinityCount > 0);
- m_dwThreadAffinityCount --;
- }
-
- static void BeginThreadAffinityAndCriticalRegion()
- {
- LIMITED_METHOD_CONTRACT;
- BeginThreadAffinity();
- GetThread()->BeginCriticalRegion();
- }
-
- static void EndThreadAffinityAndCriticalRegion()
- {
- LIMITED_METHOD_CONTRACT;
- GetThread()->EndCriticalRegion();
- EndThreadAffinity();
- }
-#endif // !FEATURE_CORECLR
BOOL HasThreadAffinity()
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- return m_dwThreadAffinityCount > 0;
-#else
return FALSE;
-#endif
}
private:
//
// In Telesto, we don't support true appdomain marshaling so the "orBlob" is in fact an
// agile wrapper object whose ToString() echoes the original exception's ToString().
-#ifdef FEATURE_CORECLR
typedef OBJECTREF ORBLOBREF;
-#else
- typedef U1ARRAYREF ORBLOBREF;
-#endif
RaiseCrossContextResult TryRaiseCrossContextException(Exception **ppExOrig,
Exception *pException,
static bool SysStartSuspendForDebug(AppDomain *pAppDomain);
static bool SysSweepThreadsForDebug(bool forceSync);
static void SysResumeFromDebug(AppDomain *pAppDomain);
-#ifndef FEATURE_CORECLR
- void UserSuspendThread();
- BOOL UserResumeThread();
-#endif // FEATURE_CORECLR
void UserSleep(INT32 time);
// For getting a thread to a safe point. A client waits on the event, which is
// set by the thread when it reaches a safe spot.
-#ifndef FEATURE_CORECLR
- void FinishSuspendingThread();
-#endif // FEATURE_CORECLR
void SetSafeEvent();
public:
LCID GetThreadCultureIdNoThrow(Thread *pThread, BOOL bUICulture);
-#ifndef FEATURE_CORECLR
-// Request/Remove Thread Affinity for the current thread
-typedef StateHolder<Thread::BeginThreadAffinityAndCriticalRegion, Thread::EndThreadAffinityAndCriticalRegion> ThreadAffinityAndCriticalRegionHolder;
-#endif // !FEATURE_CORECLR
typedef StateHolder<Thread::BeginThreadAffinity, Thread::EndThreadAffinity> ThreadAffinityHolder;
typedef Thread::ForbidSuspendThreadHolder ForbidSuspendThreadHolder;
#endif // PROFILING_SUPPORTED
-#if !defined(FEATURE_CORECLR) // simple hosting
- // First, check to see if there's an IDbgThreadControl interface that needs
- // notification of the suspension
- if (m_State & TS_DebugSuspendPending)
- {
- IDebuggerThreadControl *pDbgThreadControl = CorHost::GetDebuggerThreadControl();
-
- if (pDbgThreadControl)
- pDbgThreadControl->ThreadIsBlockingForDebugger();
-
- }
-
- if (CLRGCHosted())
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- CorHost2::GetHostGCManager()->ThreadIsBlockingForSuspension();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-
- // If not, check to see if there's an IGCThreadControl interface that needs
- // notification of the suspension
- IGCThreadControl *pGCThreadControl = CorHost::GetGCThreadControl();
-
- if (pGCThreadControl)
- pGCThreadControl->ThreadIsBlockingForSuspension();
-#endif // !defined(FEATURE_CORECLR)
DWORD status = S_OK;
SetThreadStateNC(TSNC_WaitUntilGCFinished);
#endif // PROFILING_SUPPORTED
-#if !defined(FEATURE_CORECLR) // simple hosting
- // First, check to see if there's an IDbgThreadControl interface that needs
- // notification of the suspension
- if (m_State & TS_DebugSuspendPending)
- {
- IDebuggerThreadControl *pDbgThreadControl = CorHost::GetDebuggerThreadControl();
-
- if (pDbgThreadControl)
- pDbgThreadControl->ThreadIsBlockingForDebugger();
-
- }
-
- if (CLRGCHosted())
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- CorHost2::GetHostGCManager()->ThreadIsBlockingForSuspension();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-
- // If not, check to see if there's an IGCThreadControl interface that needs
- // notification of the suspension
- IGCThreadControl *pGCThreadControl = CorHost::GetGCThreadControl();
-
- if (pGCThreadControl)
- pGCThreadControl->ThreadIsBlockingForSuspension();
-#endif // !defined(FEATURE_CORECLR)
// The thread is blocked for shutdown. We do not concern for GC violation.
CONTRACT_VIOLATION(GCViolation);
// Life's much simpler this way...
-#if !defined(FEATURE_CORECLR) // simple hosting
- // Check to see if there's an IDbgThreadControl interface that needs
- // notification of the suspension
- if (m_State & TS_DebugSuspendPending)
- {
- IDebuggerThreadControl *pDbgThreadControl = CorHost::GetDebuggerThreadControl();
-
- if (pDbgThreadControl)
- pDbgThreadControl->ThreadIsBlockingForDebugger();
-
- }
-#endif // !defined(FEATURE_CORECLR)
#endif // DEBUGGING_SUPPORTED
#ifdef LOGGING
-#if !defined(FEATURE_CORECLR) // simple hosting
- if (!CorHost::IsDebuggerSpecialThread(GetThreadId()))
-#endif // !defined(FEATURE_CORECLR)
{
LOG((LF_CORDB, LL_INFO1000, "[0x%x] SUSPEND: suspended while enabling gc.\n", GetThreadId()));
}
-#if !defined(FEATURE_CORECLR) // simple hosting
- else
- {
- LOG((LF_CORDB, LL_INFO1000,
- "[0x%x] ALERT: debugger special thread did not suspend while enabling gc.\n", GetThreadId()));
- }
-#endif // !defined(FEATURE_CORECLR)
#endif
WaitSuspendEvents(); // sets bits, too
// Notify the interface of the pending suspension
switch (reason) {
case RedirectReason_GCSuspension:
-#if !defined(FEATURE_CORECLR) // simple hosting
- if (CorHost::GetGCThreadControl())
- CorHost::GetGCThreadControl()->ThreadIsBlockingForSuspension();
- if (CLRGCHosted())
- {
- NotifyHostOnGCSuspension();
- }
-#endif // !defined(FEATURE_CORECLR)
break;
case RedirectReason_DebugSuspension:
-#if !defined(FEATURE_CORECLR) // simple hosting
- if (CorHost::GetDebuggerThreadControl() && CorHost::IsDebuggerSpecialThread(pThread->GetThreadId()))
- CorHost::GetDebuggerThreadControl()->ThreadIsBlockingForDebugger();
-#endif // !defined(FEATURE_CORECLR)
break;
case RedirectReason_UserSuspension:
// Do nothing;
STRESS_LOG1(LF_SYNC, LL_INFO1000, "Thread::SuspendRuntime(reason=0x%x)\n", reason);
-#if !defined(FEATURE_CORECLR) // simple hosting
- // Alert the host that a GC is starting, in case the host is scheduling threads
- // for non-runtime tasks during GC.
- IGCThreadControl *pGCThreadControl = CorHost::GetGCThreadControl();
-
- if (pGCThreadControl)
- pGCThreadControl->SuspensionStarting();
-
- if (CLRGCHosted())
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- CorHost2::GetHostGCManager()->SuspensionStarting();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // !defined(FEATURE_CORECLR)
#ifdef PROFILING_SUPPORTED
// If the profiler desires information about GCs, then let it know that one
// Notify everyone who cares, that this suspension is over, and this thread is going to go do other things.
//
-#if !defined(FEATURE_CORECLR) // simple hosting
- // Alert the host that a GC is ending, in case the host is scheduling threads
- // for non-runtime tasks during GC.
- IGCThreadControl *pGCThreadControl = CorHost::GetGCThreadControl();
-
- if (pGCThreadControl)
- {
- // If we the suspension was for a GC, tell the host what generation GC.
- DWORD Generation = (bFinishedGC
- ? GCHeapUtilities::GetGCHeap()->GetCondemnedGeneration()
- : ~0U);
-
- pGCThreadControl->SuspensionEnding(Generation);
- }
-
- if (CLRGCHosted())
- {
- // If we the suspension was for a GC, tell the host what generation GC.
- DWORD Generation = (bFinishedGC
- ? GCHeapUtilities::GetGCHeap()->GetCondemnedGeneration()
- : ~0U);
-
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- CorHost2::GetHostGCManager()->SuspensionEnding(Generation);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // !defined(FEATURE_CORECLR)
#ifdef PROFILING_SUPPORTED
// Need to give resume event for the GC thread
// Caller is expected to be holding the ThreadStore lock
_ASSERTE(ThreadStore::HoldingThreadStore() || IsAtProcessExit());
-#if !defined(FEATURE_CORECLR) // simple hosting
- // If there is a debugging thread control object, tell it we're suspending the Runtime.
- IDebuggerThreadControl *pDbgThreadControl = CorHost::GetDebuggerThreadControl();
-
- if (pDbgThreadControl)
- pDbgThreadControl->StartBlockingForDebugger(0);
-#endif // !defined(FEATURE_CORECLR)
// NOTE::NOTE::NOTE::NOTE::NOTE
// This function has parallel logic in SuspendRuntime. Please make
LOG((LF_CORDB, LL_INFO1000, "RESUME: starting resume AD:0x%x.\n", pAppDomain));
-#if !defined(FEATURE_CORECLR) // simple hosting
- // Notify the client that it should release any threads that it had doing work
- // while the runtime was debugger-suspended.
- IDebuggerThreadControl *pIDTC = CorHost::GetDebuggerThreadControl();
- if (pIDTC)
- {
- LOG((LF_CORDB, LL_INFO1000, "RESUME: notifying IDebuggerThreadControl client.\n"));
- pIDTC->ReleaseAllRuntimeThreads();
- }
-#endif // !defined(FEATURE_CORECLR)
// Make sure we completed the previous sync
_ASSERTE(m_DebugWillSyncCount == -1);
LOG((LF_CORDB, LL_INFO1000, "RESUME: resume complete. Trap count: %d\n", g_TrapReturningThreads.Load()));
}
-#ifndef FEATURE_CORECLR
-
-// Suspend a thread at the system level. We distinguish between user suspensions,
-// and system suspensions so that a VB program cannot resume a thread we have
-// suspended for GC.
-//
-// This service won't return until the suspension is complete. This deserves some
-// explanation. The thread is considered to be suspended if it can make no further
-// progress within the EE. For example, a thread that has exited the EE via
-// COM Interop or N/Direct is considered suspended -- if we've arranged it so that
-// the thread cannot return back to the EE without blocking.
-void Thread::UserSuspendThread()
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- // Read the general comments on thread suspension earlier, to understand why we
- // take these locks.
-
- // GC can occur in here:
- STRESS_LOG0(LF_SYNC, LL_INFO100, "UserSuspendThread obtain lock\n");
- ThreadStoreLockHolder tsl;
-
- // User suspensions (e.g. from VB and C#) are distinguished from internal
- // suspensions so a poorly behaved program cannot resume a thread that the system
- // has suspended for GC.
- if (m_State & TS_UserSuspendPending)
- {
- // This thread is already experiencing a user suspension, so ignore the
- // new request.
- _ASSERTE(!ThreadStore::HoldingThreadStore(this));
- }
- else
- if (this != GetThread())
- {
- // First suspension of a thread other than the current one.
- if (m_State & TS_Unstarted)
- {
- // There is an important window in here. T1 can call T2.Start() and then
- // T2.Suspend(). Suspend is disallowed on an unstarted thread. But from T1's
- // point of view, T2 is started. In reality, T2 hasn't been scheduled by the
- // OS, so it is still an unstarted thread. We don't want to perform a normal
- // suspension on it in this case, because it is currently contributing to the
- // PendingThreadCount. We want to get it fully started before we suspend it.
- // This is particularly important if its background status is changing
- // underneath us because otherwise we might not detect that the process should
- // be exited at the right time.
- //
- // It turns out that this is a simple situation to implement. We are holding
- // the ThreadStoreLock. TransferStartedThread will likewise acquire that
- // lock. So if we detect it, we simply set a bit telling the thread to
- // suspend itself. This is NOT the normal suspension request because we don't
- // want the thread to suspend until it has fully started.
- FastInterlockOr((ULONG *) &m_State, TS_SuspendUnstarted);
- }
- else if (m_State & (TS_Detached | TS_Dead))
- {
- return;
- }
- else
- {
- // We just want to trap this thread if it comes back into cooperative mode
- SetupForSuspension(TS_UserSuspendPending);
- m_SafeEvent.Reset();
-
- // Pause it so we can operate on it without it squirming under us.
-RetrySuspension:
- // We can not allocate memory after we suspend a thread.
- // Otherwise, we may deadlock the process when CLR is hosted.
- ThreadStore::AllocateOSContext();
-
- SuspendThreadResult str = SuspendThread();
-
- // The only safe place to suspend a thread asynchronously is if it is in
- // fully interruptible cooperative JIT code. Preemptive mode can hold all
- // kinds of locks that make it unsafe to suspend. All other cases are
- // handled somewhat synchronously (e.g. through hijacks, GC mode toggles, etc.)
- //
- // For example, on a SMP if the thread is blocked waiting for the ThreadStore
- // lock, it can cause a deadlock if we suspend it (even though it is in
- // preemptive mode).
- //
- // If a thread is in preemptive mode (including the tricky optimized N/Direct
- // case), we can just mark it for suspension. It will make no further progress
- // in the EE.
- if (str == STR_NoStressLog)
- {
- // We annot assume anything about the thread's current state.
- goto RetrySuspension;
- }
- else if (!m_fPreemptiveGCDisabled)
- {
- MarkForSuspension(TS_UserSuspendPending);
-
- // Let the thread run until it reaches a safe spot.
- if (str == STR_Success)
- {
- ResumeThread();
- }
- }
- else if (str == STR_Failure || str == STR_UnstartedOrDead)
- {
- // The thread cannot be unstarted, as we have already
- // checked for that above.
- _ASSERTE(!(m_State & TS_Unstarted));
-
- // Nothing to do if the thread has already terminated.
- }
- else if (str == STR_SwitchedOut)
- {
- goto RetrySuspension;
- }
- else
- {
- _ASSERTE(str == STR_Success);
-#if defined(FEATURE_HIJACK) && !defined(PLATFORM_UNIX)
- WorkingOnThreadContextHolder workingOnThreadContext(this);
- if (workingOnThreadContext.Acquired() && HandledJITCase())
- {
- _ASSERTE(m_fPreemptiveGCDisabled);
- // Redirect thread so we can capture a good thread context
- // (GetThreadContext is not sufficient, due to an OS bug).
- // If we don't succeed (should only happen on Win9X, due to
- // a different OS bug), we must resume the thread and try
- // again.
- if (!CheckForAndDoRedirectForUserSuspend())
- {
- ResumeThread();
- goto RetrySuspension;
- }
- }
-#endif // FEATURE_HIJACK && !PLATFORM_UNIX
-
- // Thread is executing in cooperative mode. We're going to have to
- // move it to a safe spot.
- MarkForSuspension(TS_UserSuspendPending);
-
- // Let the thread run until it reaches a safe spot.
- ResumeThread();
-
- // wait until it leaves cooperative GC mode or is JIT suspended
- FinishSuspendingThread();
- }
- }
- }
- else
- {
- GCX_PREEMP();
- SetupForSuspension(TS_UserSuspendPending);
- MarkForSuspension(TS_UserSuspendPending);
-
- // prepare to block ourselves
- tsl.Release();
- _ASSERTE(!ThreadStore::HoldingThreadStore(this));
-
- WaitSuspendEvents();
- }
-}
-
-
-// if the only suspension of this thread is user imposed, resume it. But don't
-// resume from any system suspensions (like GC).
-BOOL Thread::UserResumeThread()
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- // If we are attempting to resume when we aren't in a user suspension,
- // its an error.
- BOOL res = FALSE;
-
- // Note that the model does not count. In other words, you can call Thread.Suspend()
- // five times and Thread.Resume() once. The result is that the thread resumes.
-
- STRESS_LOG0(LF_SYNC, INFO3, "UserResumeThread obtain lock\n");
- ThreadStoreLockHolder TSLockHolder;
-
- // If we have marked a thread for suspension, while that thread is still starting
- // up, simply remove the bit to resume it.
- if (m_State & TS_SuspendUnstarted)
- {
- _ASSERTE((m_State & TS_UserSuspendPending) == 0);
- FastInterlockAnd((ULONG *) &m_State, ~TS_SuspendUnstarted);
- res = TRUE;
- }
-
- // If we are still trying to suspend the thread, forget about it.
- if (m_State & TS_UserSuspendPending)
- {
- ReleaseFromSuspension(TS_UserSuspendPending);
- SetSafeEvent();
- res = TRUE;
- }
-
- return res;
-}
-
-
-// We are asynchronously trying to suspend this thread. Stay here until we achieve
-// that goal (in fully interruptible JIT code), or the thread dies, or it leaves
-// the EE (in which case the Pending flag will cause it to synchronously suspend
-// itself later, or if the thread tells us it is going to synchronously suspend
-// itself because of hijack activity, etc.
-void Thread::FinishSuspendingThread()
-{
- CONTRACTL {
- NOTHROW;
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- }
- CONTRACTL_END;
-
- DWORD res;
-
- // There are two threads of interest -- the current thread and the thread we are
- // going to wait for. Since the current thread is about to wait, it's important
- // that it be in preemptive mode at this time.
-
-#if _DEBUG
- DWORD dbgTotalTimeout = 0;
-#endif
-
- // Wait for us to enter the ping period, then check if we are in interruptible
- // JIT code.
- while (TRUE)
- {
- ThreadSuspend::UnlockThreadStore();
- res = m_SafeEvent.Wait(PING_JIT_TIMEOUT,FALSE);
- STRESS_LOG0(LF_SYNC, INFO3, "FinishSuspendingThread obtain lock\n");
- ThreadSuspend::LockThreadStore(ThreadSuspend::SUSPEND_OTHER);
-
- if (res == WAIT_TIMEOUT)
- {
-#ifdef _DEBUG
- if ((dbgTotalTimeout += PING_JIT_TIMEOUT) >= g_pConfig->SuspendDeadlockTimeout())
- {
- _ASSERTE(!"Timeout detected trying to synchronously suspend a thread");
- dbgTotalTimeout = 0;
- }
-#endif
- // Suspend the thread and see if we are in interruptible code (placing
- // a hijack if warranted).
-#if defined(FEATURE_HIJACK) && !defined(PLATFORM_UNIX)
- RetrySuspension:
-#endif
- // The thread is detached/dead. Suspend is no op.
- if (m_State & (TS_Detached | TS_Dead))
- {
- return;
- }
-
- // We can not allocate memory after we suspend a thread.
- // Otherwise, we may deadlock the process when CLR is hosted.
- ThreadStore::AllocateOSContext();
-
- SuspendThreadResult str = SuspendThread();
-
- if (m_fPreemptiveGCDisabled && str == STR_Success)
- {
-#if defined(FEATURE_HIJACK) && !defined(PLATFORM_UNIX)
- WorkingOnThreadContextHolder workingOnThreadContext(this);
- if (workingOnThreadContext.Acquired() && HandledJITCase())
- {
- _ASSERTE(m_State & TS_UserSuspendPending);
- // Redirect thread so we can capture a good thread context
- // (GetThreadContext is not sufficient, due to an OS bug).
- // If we don't succeed (should only happen on Win9X, due to
- // a different OS bug), we must resume the thread and try
- // again.
- if (!CheckForAndDoRedirectForUserSuspend())
- {
- ResumeThread();
- goto RetrySuspension;
- }
- }
-#endif // FEATURE_HIJACK && !PLATFORM_UNIX
- // Keep trying...
- ResumeThread();
- }
- else if (!m_fPreemptiveGCDisabled)
- {
- // The thread has transitioned out of the EE. It can't get back in
- // without synchronously suspending itself. We can now return to our
- // caller since this thread cannot make further progress within the
- // EE.
- if (str == STR_Success)
- {
- ResumeThread();
- }
- break;
- }
- else if (str == STR_SwitchedOut)
- {
- // The task has been switched out while in Cooperative GC mode.
- // We will wait for the thread again.
- }
- }
- else
- {
- // SafeEvent has been set so we don't need to actually suspend. Either
- // the thread died, or it will enter a synchronous suspension based on
- // the UserSuspendPending bit.
- _ASSERTE(res == WAIT_OBJECT_0);
- _ASSERTE(!ThreadStore::HoldingThreadStore(this));
- break;
- }
- }
-}
-
-#endif // FEATURE_CORECLR
void Thread::SetSafeEvent()
return hMod;
}
-#ifndef FEATURE_CORECLR
-static ICLRRuntimeInfo *GetCLRRuntime()
-{
- LIMITED_METHOD_CONTRACT;
- return g_pCLRRuntime;
-}
-#endif // !FEATURE_CORECLR
#endif // !FEATURE_PAL
{
func = (void*)EEHeapFreeInProcessHeap;
}
-#ifndef FEATURE_CORECLR
- else if (strcmp(FunctionName, "GetCLRRuntime") == 0)
- {
- func = (void*)GetCLRRuntime;
- }
-#endif // !FEATURE_CORECLR
else if (strcmp(FunctionName, "ShutdownRuntimeWithoutExiting") == 0)
{
func = (void*)ShutdownRuntimeWithoutExiting;
extern LONG g_OLEAUT32_Loaded;
-#ifndef FEATURE_CORECLR
-#define ENSURE_OLEAUT32_LOADED() \
-{ \
- /* Should only be used in FCALL */ \
- _ASSERTE (__me != 0); \
- if (g_OLEAUT32_Loaded == 0) \
- { \
- /* CLRLoadLibrary/CLRFreeLibrary claim they trigger, but this */ \
- /* isn't really true in this case because we're loading oleaut32 */ \
- /* which we know doesn't contain any managed code in its DLLMain */ \
- CONTRACT_VIOLATION(GCViolation|SOToleranceViolation); \
- HMODULE hMod = CLRLoadLibrary(W("oleaut32")); \
- if (hMod == NULL) \
- { \
- __FCThrow(__me, kOutOfMemoryException, 0, 0, 0, 0); \
- } \
- else \
- { \
- if (FastInterlockExchange(&g_OLEAUT32_Loaded, 1) == 1) \
- { \
- CLRFreeLibrary(hMod); \
- } \
- } \
- } \
-} \
-INDEBUG(DisableDelayLoadCheckForOleaut32 _disableOleaut32Check);
-#else // !FEATURE_CORECLR
#define ENSURE_OLEAUT32_LOADED()
-#endif // !FEATURE_CORECLR
BOOL DbgIsExecutable(LPVOID lpMem, SIZE_T length);
#ifdef FEATURE_CER
GPTR_IMPL(MethodTable, g_pCriticalFinalizerObjectClass);
#endif
-#ifndef FEATURE_CORECLR
-GPTR_IMPL(MethodTable, g_pAsyncFileStream_AsyncResultClass);
-#endif // !FEATURE_CORECLR
GPTR_IMPL(MethodTable, g_pFreeObjectMethodTable);
GPTR_IMPL(MethodTable, g_pOverlappedDataClass);
// <TODO> @TODO Remove eventually - </TODO> determines whether the verifier throws an exception when something fails
bool g_fVerifierOff;
-#ifndef FEATURE_CORECLR
-IAssemblyUsageLog *g_pIAssemblyUsageLogGac;
-#endif
// <TODO> @TODO - PROMOTE. </TODO>
OBJECTHANDLE g_pPreallocatedOutOfMemoryException;
#include <corpriv.h>
#include <cordbpriv.h>
-#ifndef FEATURE_CORECLR
-#include <metahost.h>
-#endif // !FEATURE_CORECLR
#include "eeprofinterfaces.h"
#include "eehash.h"
#ifdef FEATURE_CER
GPTR_DECL(MethodTable, g_pCriticalFinalizerObjectClass);
#endif
-#ifndef FEATURE_CORECLR
-GPTR_DECL(MethodTable, g_pAsyncFileStream_AsyncResultClass);
-#endif // !FEATURE_CORECLR
GPTR_DECL(MethodTable, g_pOverlappedDataClass);
GPTR_DECL(MethodTable, g_TypedReferenceMT);
//<TODO> @TODO Remove eventually - determines whether the verifier throws an exception when something fails</TODO>
EXTERN bool g_fVerifierOff;
-#ifndef FEATURE_CORECLR
-EXTERN IAssemblyUsageLog *g_pIAssemblyUsageLogGac;
-#endif
// Global System Information
extern SYSTEM_INFO g_SystemInfo;
EXTERN BOOL g_fComStarted;
#endif
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-//
-// Pointer to the activated CLR interface provided by the shim.
-//
-EXTERN ICLRRuntimeInfo *g_pCLRRuntime;
-#endif
//
// Global state variables indicating which stage of shutdown we are in
#include "guidfromname.h"
#include "../dlls/mscorrc/resource.h"
#include "zaplog.h"
-#ifndef FEATURE_CORECLR
-#include "eventmsg.h"
-#endif // FEATURE_CORECLR
#include "ndpversion.h"
#include "loaderheap.h"
return pCorSvcLogger;
}
-#ifndef FEATURE_CORECLR
-
-void InitNGenOptions(NGenOptions *ngo,
- NGenPrivateAttributes ngenPrivateAttributes,
- OptimizationScenario optScenario = ScenarioDefault,
- LPCWSTR lpszRepositoryDir = NULL, RepositoryFlags repositoryFlags = RepositoryDefault)
-{
- ULONG_PTR pScenario = (ULONG_PTR) optScenario;
-
- ngo->dwSize = sizeof(NGenOptions);
-
- // V1
- //
- ngo->fDebug = (pScenario & ScenarioDebug) ? true : false;
- ngo->fDebugOpt = false;
- ngo->fProf = (pScenario & ScenarioProfile) ? true : false;
- ngo->fSilent = false;
- ngo->lpszExecutableFileName = NULL;
-
- // V2 (Whidbey)
- //
- ngo->fInstrument = (pScenario & ScenarioTuningDataCollection) ? true : false;
- ngo->fWholeProgram = false;
- ngo->fProfInfo = (pScenario & ScenarioProfileInfo) ? true : false;
-
- ngo->lpszRepositoryDir = lpszRepositoryDir;
- ngo->repositoryFlags = repositoryFlags;
-
- ngo->dtRequested = DT_NIL;
- ngo->lpszDebugDir = NULL;
-
- ngo->fNoInstall = false;
- ngo->fEmitFixups = false;
- ngo->fFatHeaders = false;
- ngo->fVerbose = false;
-
- // This should be a value from the StatOptions enumeration
- ngo->uStats = ngenPrivateAttributes.ZapStats;
- ngo->dtRequested = (ngenPrivateAttributes.Flags & DbgTypePdb) ? DT_PDB : DT_NIL;
- ngo->lpszDebugDir = ngenPrivateAttributes.DbgDir;
-
-
- // V4
- //
- ngo->fNgenLastRetry = (pScenario & ScenarioNgenLastRetry) ? true : false;
-
- // V4.5
- ngo->fAutoNGen = (pScenario & ScenarioAutoNGen) ? true : false;
-
- // Blue
- ngo->fRepositoryOnly = (pScenario & ScenarioRepositoryOnly) ? true : false;
-}
-
-#endif // !FEATURE_CORECLR
namespace
{
}
#endif
-#ifndef FEATURE_CORECLR
-
-//*****************************************************************************
-// ICorSvcDependencies is used to enumerate the dependencies of an
-// IL image. It is used by the native image service.
-//*****************************************************************************[
-class CCorSvcDependencies : public ICorSvcDependencies
-{
-public:
- CCorSvcDependencies()
- {
- _cRef = 0;
- zapper = NULL;
-
- g_pLocalServerLifetime->AddRefServerProcess();
- }
-
- ~CCorSvcDependencies()
- {
- if (zapper != NULL)
- {
- delete zapper;
- }
-
- g_pLocalServerLifetime->ReleaseServerProcess();
- }
-
- void Initialize(BSTR pApplicationName, OptimizationScenario scenario)
- {
- NGenOptions opt = {0};
- NGenPrivateAttributesClass ngenPrivateAttributesClass;
- InitNGenOptions(&opt, ngenPrivateAttributesClass, scenario);
- opt.lpszExecutableFileName = pApplicationName;
- zapper = Zapper::NewZapper(&opt, true);
- zapper->CreateDependenciesLookupDomain();
- }
-
- STDMETHOD (GetAssemblyDependencies)(
- BSTR pAssemblyName,
- SAFEARRAY **pDependencies,
- DWORD *assemblyNGenSetting,
- BSTR *pNativeImageIdentity,
- BSTR *pAssemblyDisplayName,
- SAFEARRAY **pDependencyLoadSetting,
- SAFEARRAY **pDependencyNGenSetting
- )
- {
- SO_NOT_MAINLINE_FUNCTION;
-
- _ASSERTE(zapper != NULL);
- _ASSERTE(pNativeImageIdentity);
-
- HRESULT hr = S_OK;
- EX_TRY
- {
- GUID nativeImageSign = INVALID_NGEN_SIGNATURE;
- zapper->ComputeDependencies(pAssemblyName, &nativeImageSign);
-
- BSTRHolder displayNameHolder(::SysAllocString(zapper->m_assemblyDependencies.GetDisplayName()));
-
- *pDependencies = zapper->m_assemblyDependencies.GetSAFEARRAY();
- *assemblyNGenSetting = zapper->m_assemblyDependencies.GetNGenHint();
- *pDependencyLoadSetting = zapper->m_assemblyDependencies.GetLoadHintSAFEARRAY();
- *pDependencyNGenSetting = zapper->m_assemblyDependencies.GetNGenHintSAFEARRAY();
-
- if (nativeImageSign != INVALID_NGEN_SIGNATURE)
- {
- WCHAR szGuid[64];
- if (GuidToLPWSTR(nativeImageSign, szGuid, sizeof(szGuid) / sizeof(WCHAR)) == 0)
- {
- ThrowHR(E_UNEXPECTED);
- }
- *pNativeImageIdentity = ::SysAllocString(szGuid);
- }
-
- *pAssemblyDisplayName = displayNameHolder.Extract();
- }
- EX_CATCH_HRESULT_AND_NGEN_CLEAN(hr);
-
- return hr;
- }
-
- STDMETHODIMP_(ULONG) AddRef()
- {
- return InterlockedIncrement (&_cRef);
- }
-
- STDMETHODIMP_(ULONG) Release()
- {
- SO_NOT_MAINLINE_FUNCTION;
-
- ULONG lRet = InterlockedDecrement (&_cRef);
- if (!lRet)
- delete this;
- return lRet;
- }
-
- STDMETHODIMP QueryInterface(REFIID riid,void ** ppv)
- {
- SO_NOT_MAINLINE_FUNCTION;
-
- if (!ppv)
- return E_POINTER;
-
- if (IsEqualIID(riid, IID_IUnknown) ||
- IsEqualIID(riid, IID_ICorSvcDependencies))
- {
- *ppv = static_cast<ICorSvcDependencies*> (this);
- AddRef();
- return S_OK;
- }
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- }
-
-private:
- LONG _cRef;
- Zapper *zapper;
-};
-
-//*****************************************************************************
-// CCorSvcCreatePdbWorker is used to load the CLR, initialize an appdomain,
-// load the given assembly and create a PDB for it.
-//*****************************************************************************
-class CCorSvcCreatePdbWorker {
-
-public:
-
- CCorSvcCreatePdbWorker()
- : m_pZapper(NULL)
- {
- }
-
- ~CCorSvcCreatePdbWorker()
- {
- if (m_pZapper)
- delete m_pZapper;
- }
-
- void Initialize(BSTR pAppBaseOrConfig, OptimizationScenario scenario)
- {
- _ASSERTE(m_pZapper == NULL);
-
- NGenOptions options = {0};
- NGenPrivateAttributesClass privateAttributesClass;
-
- InitNGenOptions(&options, privateAttributesClass, scenario);
- options.lpszExecutableFileName = pAppBaseOrConfig;
- m_pZapper = Zapper::NewZapper(&options, true);
- m_pZapper->CreateDependenciesLookupDomain();
- }
-
-
- HRESULT CreatePdb(BSTR pAssemblyName, BSTR pNativeImagePath, BSTR pPdbPath, BOOL pdbLines, BSTR pManagedPdbSearchPath)
- {
- SO_NOT_MAINLINE_FUNCTION;
- _ASSERTE(m_pZapper);
-
- HRESULT hr = S_OK;
- EX_TRY {
-
- m_pZapper->CreatePdb(pAssemblyName, pNativeImagePath, pPdbPath, pdbLines, pManagedPdbSearchPath);
-
- } EX_CATCH_HRESULT_AND_NGEN_CLEAN(hr);
-
- return hr;
- }
-
-private:
-
- Zapper *m_pZapper;
-
-};
-
-#ifdef _DEBUG
- inline void DoFreeEnvironmentStrings(LPTCH lpszEnvironmentBlock)
- {
- WszFreeEnvironmentStrings(lpszEnvironmentBlock);
- }
- typedef Wrapper<LPTCH, DoNothing, DoFreeEnvironmentStrings> EnvHolder;
-#endif //_DEBUG
-
-//*****************************************************************************
-// ICorSvcWorker contains methods for generating native images and enumerating
-// their dependencies.
-//*****************************************************************************[
-class CCorSvcWorker :
- public ICorSvcWorker3,
- public ICorSvcRepository,
- public ICorSvcSetPrivateAttributes,
-#ifdef FEATURE_APPX
- public ICorSvcAppX,
-#endif
- public ICorSvcPooledWorker
-{
-public:
- CCorSvcWorker() :
- _cRef(0),
- repositoryDir(NULL),
- repositoryFlags(RepositoryDefault),
- ngenPrivateAttributesClass()
-
-#ifdef FEATURE_FUSION
- ,
- pAssemblyCache(NULL)
-#endif
- {
- g_pLocalServerLifetime->AddRefServerProcess();
- }
-
- ~CCorSvcWorker()
- {
-#ifdef FEATURE_FUSION
- if (pAssemblyCache != NULL)
- {
- pAssemblyCache->Release();
- pAssemblyCache = NULL;
- }
-#endif
-
- GetSvcLogger()->ReleaseLogger();
-
- g_pLocalServerLifetime->ReleaseServerProcess();
- }
-
- STDMETHOD (SetPriority)(
- /*[in]*/ SvcWorkerPriority priority
- )
- {
- HRESULT hr = E_FAIL;
-
- // Set ourselves to the priority
- if (::SetPriorityClass(GetCurrentProcess(), priority.dwPriorityClass) == FALSE)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto DONE;
- }
-
- hr = S_OK;
- DONE:
- return hr;
- }
-
-#ifdef _DEBUG
- void Debug_CheckPPLProcessStatus(
- LPCWSTR wszAssemblyName)
- {
- size_t cchAssemblyName = wcslen(wszAssemblyName);
-
- // Check if we are in PPL (Protected Process Lightweight) by checking existence of LOCALAPPDATA env. var. (it is not present in PPL)
- BOOL fIsProcessPPL = TRUE;
- EnvHolder pEnvironmentStrings(WszGetEnvironmentStrings());
- for (LPTCH pEnv = pEnvironmentStrings; ((pEnv != NULL) && (*pEnv != W('\0'))); pEnv += wcslen(pEnv) + 1)
- {
- static const WCHAR const_wszLocalAppData[] = W("LOCALAPPDATA=");
- static const size_t const_cchLocalAppData = _countof(const_wszLocalAppData) - 1;
- if (_wcsnicmp(pEnv, const_wszLocalAppData, const_cchLocalAppData) == 0)
- { // LOCALAPPDATA is never set in PPL process
- fIsProcessPPL = FALSE;
- break;
- }
- }
-
- // Semicolon-separated list of names that should assert a failure
- NewArrayHolder<WCHAR> wszAssertList = NULL;
- if (fIsProcessPPL)
- { // If we are in PPL, we should assert for assemblies that are fobidden to be ngen'd in PPL
- CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NGenProtectedProcess_ForbiddenList, &wszAssertList);
- }
- else
- { // If we are not in PPL, we should assert for assemblies that require to be ngen'd in PPL
- CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NGenProtectedProcess_RequiredList, &wszAssertList);
- }
-
- if ((wszAssertList != NULL) && (*wszAssertList != W('\0')))
- {
- LPCWSTR pAssertListName = wszAssertList;
- for (;;)
- {
- LPCWSTR pAssertListNameEnd = wcschr(pAssertListName, W(';'));
- size_t cchAssertListName;
- if (pAssertListNameEnd == NULL)
- { // There is not another semicolon
- cchAssertListName = wcslen(pAssertListName);
- }
- else
- {
- cchAssertListName = pAssertListNameEnd - pAssertListName;
- }
-
- if ((cchAssertListName > 0) && (cchAssertListName <= cchAssemblyName))
- {
- // Check prefix or suffix of assembly name (which is either file name or assembly identity name)
- if ((_wcsnicmp(wszAssemblyName, pAssertListName, cchAssertListName) == 0) ||
- (_wcsnicmp(wszAssemblyName + cchAssemblyName - cchAssertListName, pAssertListName, cchAssertListName) == 0))
- {
- if (fIsProcessPPL)
- {
- _ASSERTE_MSG(FALSE, "Assembly that is in NGenProtectedProcess_ForbiddenList is ngen'd in PPL process!");
- }
- else
- {
- _ASSERTE_MSG(FALSE, "Assembly that is in NGenProtectedProcess_RequiredList is ngen'd in normal (non-PPL) process!");
- }
- }
- }
-
- if (pAssertListNameEnd == NULL)
- { // There are no more names in the semicolon-separated list
- break;
- }
-
- // Move to next item in the semicolon-separated list (skip also the semicolon)
- pAssertListName = pAssertListNameEnd + 1;
- }
- }
- } // Debug_CheckPPLProcessStatus
-#endif //_DEBUG
-
- STDMETHOD (OptimizeAssembly)(
- BSTR pAssemblyName,
- BSTR pApplicationName,
- OptimizationScenario scenario,
- SAFEARRAY *loadAlwaysList,
- SAFEARRAY *loadSometimesList,
- SAFEARRAY *loadNeverList,
- BSTR *pNativeImageIdentity
- )
- {
- SO_NOT_MAINLINE_FUNCTION;
-
- INDEBUG(Debug_CheckPPLProcessStatus(pAssemblyName);)
-
- HRESULT hr = S_OK;
- EX_TRY
- {
-#if defined(_DEBUG) || defined(ALLOW_LOCAL_WORKER)
- // Make sure optimize is called only once per process
- static int OptimizeCount = 0;
-#ifdef ALLOW_LOCAL_WORKER
- if (OptimizeCount != 0)
- {
- GetSvcLogger()->Printf(W("You cannot call OptimizeAssembly twice. If you are using COMPlus_NgenLocalWorker, make sure you are only optimizing one assembly.\r\n"));
- ThrowHR(E_FAIL);
- }
-#else // _DEBUG
- _ASSERTE(OptimizeCount == 0);
-#endif
- OptimizeCount++;
-#endif
-
- NGenOptions opt = {0};
- InitNGenOptions(&opt, ngenPrivateAttributesClass, scenario, repositoryDir, repositoryFlags);
- opt.lpszExecutableFileName = pApplicationName;
-
- GUID nativeImageSign;
- bool hasProfileData;
-
- hr = ZapperCompileWrapper(pAssemblyName, &opt, &nativeImageSign,
- loadAlwaysList, loadSometimesList, loadNeverList,
- true, &hasProfileData);
-#if 0
- // Unfotunately we can't perform a retry here as the Zapper currently
- // allocates and initializes some things once CompilationDomain and
- // thus some of this stuff will leak from the failed complation.
- //
- if (FAILED(hr) && hasProfileData && retryNgenFailures)
- {
- hr = ZapperCompileWrapper(pAssemblyName, &opt, &nativeImageSign,
- loadAlwaysList, loadSometimesList, loadNeverList,
- false, NULL);
- if (SUCCEEDED(hr))
- {
- StackSString msg;
- msg.Printf(W("The compile failed when the profile data was used and ")
- W("the compile succeeded when the profile data was ignored."));
- GetSvcLogger()->Log(msg, LogLevel_Info);
- }
- }
-#endif
- IfFailThrow(hr);
-
- _ASSERTE(nativeImageSign != INVALID_NGEN_SIGNATURE || opt.fRepositoryOnly);
-
- _ASSERTE(pNativeImageIdentity);
- if (nativeImageSign != INVALID_NGEN_SIGNATURE)
- {
- WCHAR szGuid[64];
- if (GuidToLPWSTR(nativeImageSign, szGuid, sizeof(szGuid) / sizeof(WCHAR)) == 0)
- ThrowHR(E_UNEXPECTED);
- *pNativeImageIdentity = ::SysAllocString(szGuid);
- }
- else
- {
- *pNativeImageIdentity = NULL;
- }
- }
- EX_CATCH_HRESULT_AND_NGEN_CLEAN(hr);
-
- return hr;
- }
-
- STDMETHOD (DeleteNativeImage)(
- BSTR pAssemblyName,
- BSTR pNativeImage
- )
- {
- // The caller must either specify both parameters, or specify neither.
- _ASSERTE((pAssemblyName == NULL && pNativeImage == NULL) ||
- (pAssemblyName != NULL && pNativeImage != NULL));
-
- HRESULT hr = S_OK;
- EX_TRY
- {
- NGenOptions opt = {0};
- InitNGenOptions(&opt, ngenPrivateAttributesClass);
- NewHolder<Zapper> zapper = Zapper::NewZapper(&opt, true);
- _ASSERTE(zapper != NULL);
-
- GUID *pNativeImageMVID = NULL;
- GUID nativeImageMVID;
-
- if (pNativeImage)
- {
- StackSString nativeImageString(pNativeImage);
- StackScratchBuffer buffer;
- LPCSTR pstr = nativeImageString.GetANSI(buffer);
- IfFailThrow(LPCSTRToGuid((LPCSTR) pstr, &nativeImageMVID));
- pNativeImageMVID = &nativeImageMVID;
- }
-
-#ifdef FEATURE_FUSION
- if (pAssemblyName != NULL && pNativeImageMVID != NULL)
- {
- // Deleting a specific native image.
- zapper->DeleteFusionCacheEntry(pAssemblyName, pNativeImageMVID);
- }
- else if (pAssemblyName != NULL || pNativeImageMVID != NULL)
- {
- hr = E_UNEXPECTED;
- }
- else
- {
- // Not deleting a specific native image. Need to enumerate NIC.
- IfFailThrow(zapper->EnumerateFusionCache(NULL, false, true, NULL));
- }
-#else //FEATURE_FUSION
- _ASSERTE(!"NYI");
-#endif //FEATURE_FUSION
- }
- EX_CATCH_HRESULT_AND_NGEN_CLEAN(hr);
-
- return hr;
- }
-
- STDMETHOD (DisplayNativeImages)(BSTR pAssemblyName)
- {
-#ifdef FEATURE_FUSION
- HRESULT hr = S_OK;
- EX_TRY
- {
- NGenOptions opt = {0};
- InitNGenOptions(&opt, ngenPrivateAttributesClass);
- NewHolder<Zapper> zapper = Zapper::NewZapper(&opt, true);
- _ASSERTE(zapper != NULL);
-
- IfFailThrow(zapper->EnumerateFusionCache(pAssemblyName, true, false, NULL));
- }
- EX_CATCH_HRESULT_AND_NGEN_CLEAN(hr);
-
- return hr;
-#else //FEATURE_FUSION
- return E_NOTIMPL;
-#endif //FEATURE_FUSION
- }
-
- STDMETHOD(GetCorSvcDependencies)(
- BSTR pApplicationName,
- OptimizationScenario scenario,
- ICorSvcDependencies **ppCorSvcDependencies
- )
- {
- SO_NOT_MAINLINE_FUNCTION;
-
- HRESULT hr = S_OK;
- EX_TRY
- {
- NewHolder<CCorSvcDependencies> pCorSvcDependencies(new CCorSvcDependencies());
- pCorSvcDependencies->Initialize(pApplicationName, scenario);
- IfFailThrow(pCorSvcDependencies->QueryInterface(IID_ICorSvcDependencies, (void **) ppCorSvcDependencies));
- pCorSvcDependencies.SuppressRelease();
- }
- EX_CATCH_HRESULT_AND_NGEN_CLEAN(hr);
-
- return hr;
- }
-
- STDMETHOD(Stop)()
- {
- return S_OK;
- }
-
- STDMETHOD(CreatePdb)(__in BSTR pAssemblyName,
- __in BSTR pAppBaseOrConfig,
- __in OptimizationScenario scenario,
- __in BSTR pNativeImagePath,
- __in BSTR pPdbPath)
- {
- return CreatePdb2(
- pAssemblyName,
- pAppBaseOrConfig,
- scenario,
- pNativeImagePath,
- pPdbPath,
- FALSE,
- NULL);
- }
-
- STDMETHOD(CreatePdb2)(__in BSTR pAssemblyName,
- __in BSTR pAppBaseOrConfig,
- __in OptimizationScenario scenario,
- __in BSTR pNativeImagePath,
- __in BSTR pPdbPath,
- __in BOOL pdbLines,
- __in BSTR pManagedPdbSearchPath)
- {
- SO_NOT_MAINLINE_FUNCTION;
-
- HRESULT hr = S_OK;
-
- EX_TRY {
-
- CCorSvcCreatePdbWorker worker;
- worker.Initialize(pAppBaseOrConfig, scenario);
- hr = worker.CreatePdb(pAssemblyName, pNativeImagePath, pPdbPath, pdbLines, pManagedPdbSearchPath);
-
- } EX_CATCH_HRESULT_AND_NGEN_CLEAN(hr);
-
- return hr;
- }
-
-#ifdef FEATURE_APPX
- STDMETHOD(SetPackage)(__in BSTR pPackageFullName)
- {
- return AppX::SetCurrentPackageForNGen(pPackageFullName);
- }
-
- STDMETHOD(SetLocalAppDataDirectory)(__in BSTR pLocalAppDataDirectory)
- {
- return Clr::Util::SetLocalAppDataDirectory(pLocalAppDataDirectory);
- }
-#endif
-
- STDMETHOD (SetRepository)(
- BSTR pRepositoryDir,
- RepositoryFlags flags
- )
- {
- _ASSERTE(repositoryFlags == RepositoryDefault);
- _ASSERTE(repositoryDir == NULL);
-
- repositoryDir = ::SysAllocString(pRepositoryDir);
- repositoryFlags = flags;
-
- return S_OK;
- }
-
- STDMETHOD (SetNGenPrivateAttributes)(
- NGenPrivateAttributes ngenPrivateAttributes
- )
- {
- _ASSERTE(ngenPrivateAttributesClass.Flags == 0);
- _ASSERTE(ngenPrivateAttributesClass.ZapStats == 0);
-
- ngenPrivateAttributesClass.Flags = ngenPrivateAttributes.Flags;
- ngenPrivateAttributesClass.ZapStats = ngenPrivateAttributes.ZapStats;
-
- if (ngenPrivateAttributes.DbgDir)
- {
- _ASSERTE(ngenPrivateAttributesClass.DbgDir == NULL);
- ngenPrivateAttributesClass.DbgDir = ::SysAllocString(ngenPrivateAttributes.DbgDir);
- }
-
- return S_OK;
- }
-
- STDMETHOD (CanReuseProcess)(
- OptimizationScenario scenario,
- ICorSvcLogger *pCorSvcLogger,
- BOOL *pCanContinue)
- {
- SO_NOT_MAINLINE_FUNCTION;
-
- HRESULT hr = S_OK;
-
- _ASSERTE(pCanContinue != NULL);
- *pCanContinue = FALSE;
-
- return hr;
- }
-
- static HRESULT CreateObject(REFIID riid, void **ppUnk)
- {
- HRESULT hr;
- CCorSvcWorker *pCorSvcWorker = new (nothrow) CCorSvcWorker();
-
- if (pCorSvcWorker == 0)
- return (E_OUTOFMEMORY);
-
- hr = pCorSvcWorker->QueryInterface(riid, ppUnk);
- if (FAILED(hr))
- delete pCorSvcWorker;
- return (hr);
- }
-
- STDMETHODIMP_(ULONG) AddRef()
- {
- return InterlockedIncrement (&_cRef);
- }
-
- STDMETHODIMP_(ULONG) Release()
- {
- ULONG lRet = InterlockedDecrement (&_cRef);
- if (!lRet)
- delete this;
- return lRet;
- }
-
- STDMETHODIMP QueryInterface(REFIID riid,void ** ppv)
- {
- if (!ppv)
- return E_POINTER;
-
- if (IsEqualIID(riid, IID_IUnknown) ||
- IsEqualIID(riid, IID_ICorSvcWorker))
- {
- *ppv = static_cast<ICorSvcWorker*> (this);
- AddRef();
- return S_OK;
- }
- else if (IsEqualIID(riid, IID_ICorSvcWorker2))
- {
- *ppv = static_cast<ICorSvcWorker2 *>(this);
- AddRef();
- return S_OK;
- }
- else if (IsEqualIID(riid, IID_ICorSvcWorker3))
- {
- *ppv = static_cast<ICorSvcWorker3 *>(this);
- AddRef();
- return S_OK;
- }
- else if (IsEqualIID(riid, IID_ICorSvcRepository))
- {
- *ppv = static_cast<ICorSvcRepository*> (this);
- AddRef();
- return S_OK;
- }
- else if (IsEqualIID(riid, IID_ICorSvcSetPrivateAttributes))
- {
- *ppv = static_cast<ICorSvcSetPrivateAttributes *> (this);
- AddRef();
- return S_OK;
- }
-#ifdef FEATURE_APPX
- else if (IsEqualIID(riid, IID_ICorSvcAppX))
- {
- *ppv = static_cast<ICorSvcAppX *> (this);
- AddRef();
- return S_OK;
- }
-#endif
- else if (IsEqualIID(riid, IID_ICorSvcPooledWorker))
- {
- *ppv = static_cast<ICorSvcPooledWorker *> (this);
- AddRef();
- return S_OK;
- }
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- }
-
-private:
- HRESULT ZapperCompileWrapper(BSTR pAssemblyName,
- NGenOptions * pOpt,
- GUID * pNativeImageSign,
- SAFEARRAY * loadAlwaysList,
- SAFEARRAY * loadSometimesList,
- SAFEARRAY * loadNeverList,
- bool useProfileData,
- bool * pHasProfileData)
- {
- NewHolder<Zapper> zapper(Zapper::NewZapper(pOpt, true));
-
- *pNativeImageSign = INVALID_NGEN_SIGNATURE;
-
- // Push the load lists to the zapper
- zapper->SetLoadLists(loadAlwaysList, loadSometimesList, loadNeverList);
- if (useProfileData == false)
- {
- zapper->DontUseProfileData();
- }
-
- HRESULT hr = zapper->Compile(pAssemblyName, pNativeImageSign);
-
- if (pHasProfileData != NULL)
- {
- *pHasProfileData = zapper->HasProfileData();
- }
-
- if (!FAILED(hr) && (*pNativeImageSign == INVALID_NGEN_SIGNATURE) && !pOpt->fRepositoryOnly)
- {
- // Unfortunately we can get a passing HR when an EE exception was
- // thrown because the zapper EH logic can't get the correct HR
- // out of the EE exception. This will be fixed, but for now we
- // should also return E_FAIL in that case.
-
- hr = E_FAIL;
- }
-
- return hr;
- }
-
-private:
- LONG _cRef;
-
- BSTRHolder repositoryDir;
- RepositoryFlags repositoryFlags;
-
- NGenPrivateAttributesClass ngenPrivateAttributesClass;
-
-#ifdef FEATURE_FUSION
- IAssemblyCache *pAssemblyCache;
-#endif // FEATURE_FUSION
-};
-
-STDAPI NGenCreateNGenWorker(ICorSvcWorker **pCorSvcWorker, ILocalServerLifetime *pLocalServerLifetime, ICorSvcLogger *pCorSvcLogger)
-{
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- EX_TRY
- {
- _ASSERTE(pLocalServerLifetime);
- //_ASSERTE(g_pLocalServerLifetime == NULL);
-
- g_pLocalServerLifetime = pLocalServerLifetime;
-
- GetSvcLogger()->SetSvcLogger(pCorSvcLogger);
-
- IfFailThrow(CCorSvcWorker::CreateObject(IID_ICorSvcWorker, (void **) pCorSvcWorker));
- }
- EX_CATCH_HRESULT_AND_NGEN_CLEAN(hr);
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-#endif // !FEATURE_CORECLR
: m_zapper(zapper)
/* Everything else is initialized to 0 by default */
{
-#ifndef FEATURE_CORECLR
- if (m_zapper->m_pOpt->m_statOptions)
- m_stats = new ZapperStats();
-#endif
}
ZapImage::~ZapImage()
//
// Clean up.
//
-#ifndef FEATURE_CORECLR
- if (m_stats != NULL)
- delete m_stats;
-#endif
if (m_pModuleFileName != NULL)
delete [] m_pModuleFileName;
m_pHelperThunks = new (GetHeap()) ZapNode * [CORINFO_HELP_COUNT];
-#ifdef FEATURE_CORECLR
if (!m_zapper->m_pOpt->m_fNoMetaData)
-#endif
{
m_pILMetaData = new (GetHeap()) ZapILMetaData(this);
m_pILMetaDataSection->Place(m_pILMetaData);
m_pHeaderSection->Place(m_pImportSectionsTable);
{
-#ifdef FEATURE_CORECLR
#define COMPILER_NAME "CoreCLR"
-#else
-#define COMPILER_NAME "CLR"
-#endif
const char * pCompilerIdentifier = COMPILER_NAME " " FX_FILEVERSION_STR " " QUOTE_MACRO(__BUILDMACHINE__);
ZapBlob * pCompilerIdentifierBlob = new (GetHeap()) ZapBlobPtr((PVOID)pCompilerIdentifier, strlen(pCompilerIdentifier) + 1);
HANDLE hFile = GenerateFile(wszOutputFileName, pNativeImageSig);
-#ifndef FEATURE_CORECLR
- if (m_stats != NULL)
- PrintStats(wszOutputFileName);
-#endif
#ifdef FEATURE_FUSION
CompressFile(wszOutputFileName[0], hFile);
//
// CoreCLR currently always loads both the IL and the native image, so
// move the native image out of the way.
-#ifndef FEATURE_CORECLR
- if (!m_ModuleDecoder.IsDll() || // exes always get loaded to their preferred base address
- !m_ModuleDecoder.IsILOnly()) // since the IL (IJW) image will be loaded first
-#endif // !FEATURE_CORECLR
{
baseAddress += m_ModuleDecoder.GetVirtualSize();
}
CalculateZapBaseAddress();
}
-#if !defined(FEATURE_CORECLR)
-
-#if (_WIN32_WINNT < _WIN32_WINNT_WIN8)
-
-typedef struct _WIN32_MEMORY_RANGE_ENTRY {
-
- PVOID VirtualAddress;
- SIZE_T NumberOfBytes;
-
-} WIN32_MEMORY_RANGE_ENTRY, *PWIN32_MEMORY_RANGE_ENTRY;
-
-#endif
-
-typedef BOOL
-(WINAPI *PfnPrefetchVirtualMemory)(
- _In_ HANDLE hProcess,
- _In_ ULONG_PTR NumberOfEntries,
- _In_reads_(NumberOfEntries) PWIN32_MEMORY_RANGE_ENTRY VirtualAddresses,
- _In_ ULONG Flags
- );
-
-
-void PrefetchVM(void * pStartAddress, SIZE_T size)
-{
- static PfnPrefetchVirtualMemory s_pfnPrefetchVirtualMemory = NULL;
-
- if (s_pfnPrefetchVirtualMemory == NULL)
- {
- s_pfnPrefetchVirtualMemory = (PfnPrefetchVirtualMemory) GetProcAddress(WszGetModuleHandle(WINDOWS_KERNEL32_DLLNAME_W), "PrefetchVirtualMemory");
-
- if (s_pfnPrefetchVirtualMemory == NULL)
- {
- s_pfnPrefetchVirtualMemory = (PfnPrefetchVirtualMemory) (1);
- }
- }
-
- if (s_pfnPrefetchVirtualMemory > (PfnPrefetchVirtualMemory) (1))
- {
- WIN32_MEMORY_RANGE_ENTRY range;
-
- range.VirtualAddress = pStartAddress;
- range.NumberOfBytes = size;
-
- s_pfnPrefetchVirtualMemory(GetCurrentProcess(), 1, & range, 0);
- }
-}
-
-#endif
void ZapImage::Preload()
{
-#if !defined(FEATURE_CORECLR)
- // Prefetch the whole IL image into memory to avoid small reads (usually 16kb blocks)
- PrefetchVM(m_ModuleDecoder.GetBase(), m_ModuleDecoder.GetSize());
-#endif
CorProfileData * pProfileData = NewProfileData();
m_pPreloader = m_zapper->m_pEECompileInfo->PreloadModule(m_hModule, this, pProfileData);
if (IsReadyToRunCompilation())
{
-#ifndef FEATURE_CORECLR
- // Some older versions of Windows (e.g., Win7) can incorrectly fixup
- // relocations if IsDll is not set. In CoreCLR, we handle this by
- // always using the default value of IsDll, which is true. We can't
- // use the same fix in desktop CLR, since in this case the ReadyToRun
- // image can be used to create processes.
- SetIsDll(m_ModuleDecoder.IsDll());
-#endif
SetSizeOfStackReserve(m_ModuleDecoder.GetSizeOfStackReserve());
SetSizeOfStackCommit(m_ModuleDecoder.GetSizeOfStackCommit());
#if defined(FEATURE_PAL)
// PAL library requires native image sections to align to page bounaries.
SetFileAlignment(0x1000);
-#elif defined(_TARGET_ARM_) && defined(FEATURE_CORECLR) && defined(FEATURE_CORESYSTEM)
+#elif defined(_TARGET_ARM_) && defined(FEATURE_CORESYSTEM)
if (!IsReadyToRunCompilation())
{
// On ARM CoreSys builds, crossgen will use 4k file alignment, as requested by Phone perf team
}
// CoreCLR should never be presented with V1 IBC data.
-#ifndef FEATURE_CORECLR
- if ((fileHeader->Version == CORBBTPROF_V1_VERSION) && CanConvertIbcData())
- {
- // Read and convert V1 data
- m_zapper->Info(W("Converting V1 IBC data to latest format.\n"));
- convertFromV1 = true;
- }
- else
-#endif
if (fileHeader->Version == CORBBTPROF_V3_VERSION)
{
CORBBTPROF_FILE_OPTIONAL_HEADER *optionalHeader =
level = CORZAP_LOGLEVEL_ERROR;
#endif
-#ifndef FEATURE_CORECLR
- m_zapper->Print(level, W("Warning: %s. If this assembly is found during runtime of an application, then the native image currently being generated will not be used.\n"), pszMessage);
-#else
m_zapper->Print(level, W("Warning: %s.\n"), pszMessage);
-#endif
fileNotFoundErrorsTable.Append(message);
}
void ZapImage::Error(mdToken token, HRESULT hr, LPCWSTR message)
{
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
// Missing dependencies are reported as fatal errors in code:CompilationDomain::BindAssemblySpec.
// Avoid printing redundant error message for them.
if (FAILED(g_hrFatalError))
ThrowHR(g_hrFatalError);
-#endif
CorZapLogLevel level = CORZAP_LOGLEVEL_ERROR;
return;
}
-#if !defined(FEATURE_CORECLR)
- // Ask the JIT to generate desktop-quirk-compatible code.
- m_jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DESKTOP_QUIRKS);
-#endif
if (m_pImage->m_stats)
{
int ZapInfo::doAssert(const char* szFile, int iLine, const char* szExpr)
{
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- ThrowHR(COR_E_INVALIDPROGRAM);
-#else
#if defined(_DEBUG)
return(_DbgBreakCheck(szFile, iLine, szExpr));
return(true); // break into debugger
#endif
-#endif
}
void ZapInfo::reportFatalError(CorJitResult result)
{
break;
case IMAGE_REL_BASED_PTR:
-#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR)
- _ASSERTE(!"Why we are not using RIP relative address?");
-#endif
*(UNALIGNED TADDR *)location = (TADDR)targetOffset;
break;
// if the fixups were exclusively based on the moduleforstatics lookup
cls = NULL;
-#ifndef FEATURE_CORECLR
-
- // Is this mscorlib.dll (which has ModuleDomainId of 0 (tagged == 1), then you don't need a fixup
- if (moduleId == (size_t) 1)
- {
- *ppIndirection = NULL;
- return (size_t) 1;
- }
-#endif
if (module == m_pImage->m_hModule)
{
const char * reason)
{
-#ifndef FEATURE_CORECLR
- if (!dontInline(inlineResult) && inlineeHnd != NULL)
- {
- // We deliberately report m_currentMethodHandle (not inlinerHnd) as inliner, because
- // if m_currentMethodHandle != inlinerHnd, it simply means that inlinerHnd is intermediate link
- // in inlining into m_currentMethodHandle, and we have no interest to track those intermediate links now.
- m_pImage->m_pPreloader->ReportInlining(m_currentMethodHandle, inlineeHnd);
- }
-#endif //FEATURE_CORECLR
return m_pEEJitInfo->reportInliningDecision(inlinerHnd, inlineeHnd, inlineResult, reason);
}
#include "metahost.h"
#endif
-#if defined(FEATURE_APPX) && !defined(FEATURE_CORECLR)
-#include "AppXUtil.h"
-#include "AssemblyUsageLogManager.h"
-#endif
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
#include "coregen.h"
-#endif
#include "clr/fs/dir.h"
#ifdef FEATURE_FUSION
extern const WCHAR g_pwBaseLibrary[];
extern bool g_fAllowNativeImages;
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
bool g_fNGenMissingDependenciesOk;
-#endif
bool g_fNGenWinMDResilient;
-#if !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
-extern int g_ningenState;
-#endif
#ifdef FEATURE_READYTORUN_COMPILER
bool g_fReadyToRunCompilation;
#endif
-#ifdef FEATURE_CORECLR
static bool s_fNGenNoMetaData;
-#endif
// Event logging helper
void Zapper::ReportEventNGEN(WORD wType, DWORD dwEventID, LPCWSTR format, ...)
// For side by side issues, it's best to use the exported API calls to generate a
// Zapper Object instead of creating one on your own.
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzOutputFilename=NULL, LPCWSTR pwzPlatformWinmdPaths=NULL, ICorSvcLogger *pLogger = NULL, LPCWSTR pwszCLRJITPath = nullptr)
{
ngo.fNgenLastRetry = false;
-#ifdef FEATURE_CORECLR
s_fNGenNoMetaData = (dwFlags & NGENWORKER_FLAGS_NO_METADATA) != 0;
-#endif
zap = Zapper::NewZapper(&ngo);
if (pwzPlatformWinmdPaths != nullptr)
zap->SetPlatformWinmdPaths(pwzPlatformWinmdPaths);
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
if (pwszCLRJITPath != nullptr)
zap->SetCLRJITPath(pwszCLRJITPath);
#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
zap = Zapper::NewZapper(&ngo);
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
zap->SetDontLoadJit();
#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
if (pwzPlatformWinmdPaths != nullptr)
zap->SetPlatformWinmdPaths(pwzPlatformWinmdPaths);
-#if defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#if !defined(NO_NGENPDB)
if (pwzDiasymreaderPath != nullptr)
zap->SetDiasymreaderPath(pwzDiasymreaderPath);
#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
return hr;
}
-#else // FEATURE_CORECLR || CROSSGEN_COMPILE
-
-STDAPI LegacyNGenCreateZapper(HANDLE* hZapper, NGenOptions* opt)
-{
- if (hZapper == NULL)
- return E_POINTER;
-
- HRESULT hr = S_OK;
- Zapper* zap = NULL;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
-
- EX_TRY
- {
- zap = Zapper::NewZapper(opt);
- }
- EX_CATCH_HRESULT(hr);
-
- END_ENTRYPOINT_NOTHROW;
-
- IfFailRet(hr);
-
- if (zap == NULL)
- return E_OUTOFMEMORY;
-
- zap->SetLegacyMode();
-
- *hZapper = (HANDLE)zap;
-
- return S_OK;
-}// NGenCreateZapper
-
-STDAPI LegacyNGenFreeZapper(HANDLE hZapper)
-{
- if (hZapper == NULL || hZapper == INVALID_HANDLE_VALUE)
- return E_HANDLE;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- Zapper *zapper = (Zapper*)hZapper;
- delete zapper;
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
-}// NGenFreeZapper
-
-#ifdef FEATURE_FUSION
-STDAPI LegacyNGenTryEnumerateFusionCache(HANDLE hZapper, LPCWSTR assemblyName, bool fPrint, bool fDelete)
-{
-
- HRESULT hr = S_OK;
- if (hZapper == NULL || hZapper == INVALID_HANDLE_VALUE)
- return E_HANDLE;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- Zapper *zapper = (Zapper*)hZapper;
- hr = zapper->TryEnumerateFusionCache(assemblyName, fPrint, fDelete);
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-
-}// NGenTryEnumerateFusionCache
-#endif //FEATURE_FUSION
-
-STDAPI_(BOOL) LegacyNGenCompile(HANDLE hZapper, LPCWSTR path)
-{
- CONTRACTL{
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- if (hZapper == NULL || hZapper == INVALID_HANDLE_VALUE)
- return FALSE;
-
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_VOIDRET;
-
- Zapper *zapper = (Zapper*)hZapper;
-
- EX_TRY
- {
- hr = zapper->Compile(path);
- }
- EX_CATCH_HRESULT(hr);
-
- END_ENTRYPOINT_VOIDRET;
-
- return (hr == S_OK) ? TRUE : FALSE;
-}// NGenCompile
-
-#endif // FEATURE_CORECLR || CROSSGEN_COMPILE
/* --------------------------------------------------------------------------- *
* Options class
m_fNGenLastRetry(false),
m_compilerFlags(),
m_legacyMode(false)
-#ifdef FEATURE_CORECLR
,m_fNoMetaData(s_fNGenNoMetaData)
-#endif
{
m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_RELOC);
m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PREJIT);
_ASSERTE(SUCCEEDED(hr));
#endif
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
m_fDontLoadJit = false;
#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
HRESULT hr = E_FAIL;
-#if defined(FEATURE_CORECLR) || defined(FEATURE_MERGE_JIT_AND_ENGINE)
// Note: FEATURE_MERGE_JIT_AND_ENGINE is defined for the Desktop crossgen compilation as well.
//
PathString CoreClrFolder;
extern HINSTANCE g_hThisInst;
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
if (m_fDontLoadJit)
{
return;
hr = S_OK;
}
}
-#else
- hr = g_pCLRRuntime->LoadLibrary(pwzJitName, phJit);
-#endif
if (FAILED(hr))
{
ThrowLastError();
}
-#if (defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST)) && !defined(CROSSGEN_COMPILE)
+#if !defined(CROSSGEN_COMPILE)
typedef void (__stdcall* pSxsJitStartup) (CoreClrCallbacks const & cccallbacks);
pSxsJitStartup sxsJitStartupFn = (pSxsJitStartup) GetProcAddress(*phJit, "sxsJitStartup");
if (sxsJitStartupFn == NULL)
CorCompileRuntimeDlls ngenDllId;
-#if !defined(FEATURE_CORECLR)
- ngenDllId = NGEN_COMPILER_INFO;
-#else // FEATURE_CORECLR
ngenDllId = CROSSGEN_COMPILER_INFO;
-#endif
LPCWSTR pwzJitName = CorCompileGetRuntimeDllName(ngenDllId);
LoadAndInitializeJITForNgen(pwzJitName, &m_hJitLib, &m_pJitCompiler);
-#if defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- // For reasons related to servicing, and RyuJIT rollout on .NET 4.6 and beyond, we only use RyuJIT when the registry
- // value UseRyuJIT (type DWORD), under key HKLM\SOFTWARE\Microsoft\.NETFramework, is set to 1. Otherwise, we fall back
- // to JIT64.
- //
- // See the document "RyuJIT Compatibility Fallback Specification.docx" for details.
- //
- // Also see the code and comments in EEJitManager::LoadJIT().
-
- if (!UseRyuJit()) // Do we need to fall back to JIT64 for NGEN?
- {
- LPCWSTR pwzJitName = MAKEDLLNAME_W(L"compatjit");
-
- // Note: if the compatjit fails to load, we ignore it, and continue to use the main JIT for
- // everything. You can imagine a policy where if the user requests the compatjit, and we fail
- // to load it, that we fail noisily. We don't do that currently.
- ICorJitCompiler* fallbackICorJitCompiler;
- LoadAndInitializeJITForNgen(pwzJitName, &m_hJitLegacy, &fallbackICorJitCompiler);
-
- // Tell the main JIT to fall back to the "fallback" JIT compiler, in case some
- // obfuscator tries to directly call the main JIT's getJit() function.
- m_pJitCompiler->setRealJit(fallbackICorJitCompiler);
- }
-#endif // defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
#endif // FEATURE_MERGE_JIT_AND_ENGINE
#ifdef ALLOW_SXS_JIT_NGEN
SetContextInfo();
}
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
-void ZapperSetPlatformAssembliesPaths(SString &platformAssembliesPaths);
-#endif
-#ifdef FEATURE_CORECLR
void ZapperSetBindingPaths(ICorCompilationDomain *pDomain, SString &trustedPlatformAssemblies, SString &platformResourceRoots, SString &appPaths, SString &appNiPaths);
-#endif
void Zapper::CreateCompilationDomain()
{
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- // Platform assemblies paths have to be set before appdomain is setup so that
- // mscorlib.dll can be loaded from them.
- ZapperSetPlatformAssembliesPaths(m_platformAssembliesPaths);
-#endif
BOOL fForceDebug = FALSE;
if (!m_pOpt->m_autodebug)
IfFailThrow(m_pDomain->SetPlatformWinmdPaths(m_platformWinmdPaths));
#endif
-#ifdef FEATURE_CORECLR
// we support only TPA binding on CoreCLR
if (!m_trustedPlatformAssemblies.IsEmpty())
// Add the trusted paths and apppath to the binding list
ZapperSetBindingPaths(m_pDomain, m_trustedPlatformAssemblies, m_platformResourceRoots, m_appPaths, m_appNiPaths);
}
-#endif
}
void Zapper::CreateDependenciesLookupDomain()
}
LPCWSTR pDiasymreaderPath = nullptr;
-#if defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#if !defined(NO_NGENPDB)
if (m_DiasymreaderPath.GetCount() > 0)
{
pDiasymreaderPath = m_DiasymreaderPath.GetUnicode();
}
else
{
-#if defined(FEATURE_APPX) && !defined(FEATURE_CORECLR)
- if (m_pOpt->m_fAutoNGen)
- {
- // Make sure we're not been spoofed into loading an assembly that might be unsafe to load.
- // Loading by path so we better be AppX or a WinMD
- StackSString s(pAssemblyString);
- SString literalWinMD(SString::Literal, W(".winmd"));
- BOOL isWinMD = (s.GetCount() > 6) && s.MatchCaseInsensitive(s.End() - 6, literalWinMD);
- if (!AppX::IsAppXProcess() && !isWinMD)
- {
- Error(W("Cannot load assembly %s for automatic NGen.\n"), pAssemblyString);
- ThrowHR(E_FAIL);
- }
-
- // Is AppX NGen disabled?
- if ((AssemblyUsageLogManager::GetUsageLogFlags() & AssemblyUsageLogManager::ASSEMBLY_USAGE_LOG_FLAGS_APPLOCALNGENDISABLED) != 0)
- {
- memset(pNativeImageSig, 0, sizeof(*pNativeImageSig)); // Fake NI signature to disable NGen.
- Warning(W("NGen disabled for this application.\n"));
- return;
- }
- }
-#endif
hr = m_pEECompileInfo->LoadAssemblyByPath(pAssemblyString,
FALSE, // fExplicitBindToNativeImage
IfFailThrow(hr);
}
-#ifndef FEATURE_CORECLR
- if (m_pOpt->m_fAutoNGen && !m_pEECompileInfo->SupportsAutoNGen(hAssembly))
- {
- Error(W("Assembly %s does not support automatic NGen.\n"), pAssemblyString);
- ThrowHR(E_FAIL);
- }
-#endif // FEATURE_CORECLR
//
// Check if we have a native image already, and if so get its GUID
{
fMscorlib = true;
}
-#ifndef FEATURE_CORECLR
- else
- if (_wcsnicmp(fileName, W("mscorlib"), 8) == 0 && (wcslen(fileName) == 8 || fileName[8] == W(',')))
- {
- fMscorlib = true;
- }
-#endif
-#if !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- if (fMscorlib)
- {
- //
- // Enable ningen by default for mscorlib to get identical images between ngen and crossgen
- //
- g_ningenState = 1;
- }
-#endif
-#if defined(CROSSGEN_COMPILE) || defined(FEATURE_CORECLR)
if (fMscorlib)
{
//
//
g_fAllowNativeImages = false;
}
-#endif
// the errors in CreateCompilationDomain are fatal - propogate them up
CreateCompilationDomain();
BEGIN_ENTRYPOINT_VOIDRET;
-#ifndef FEATURE_CORECLR
- // Set the hard binding list. This needs to be done early, before we attempt to use any
- // softbound native images, in order to ensure NGen determinism.
- SetAssemblyHardBindList();
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_FUSION
// Set the context info for the current domain
m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_FCOMI);
}
-#if !defined(FEATURE_CORECLR)
- if (CPU_X86_USE_SSE2(pVersionInfo->cpuInfo.dwFeatures))
- {
- m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE2);
- }
-#else
// .NET Core requires SSE2.
m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE2);
-#endif // !defined(FEATURE_CORECLR)
#endif // _TARGET_X86_
Print(level, W("%s"), message.GetUnicode());
}
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
void Zapper::SetCLRJITPath(LPCWSTR pwszCLRJITPath)
{
m_CLRJITPath.Set(pwszCLRJITPath);
}
#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
-#if defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#if !defined(NO_NGENPDB)
void Zapper::SetDiasymreaderPath(LPCWSTR pwzDiasymreaderPath)
{
m_DiasymreaderPath.Set(pwzDiasymreaderPath);
}
#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
void Zapper::SetPlatformAssembliesPaths(LPCWSTR pwzPlatformAssembliesPaths)
{
m_fForceFullTrust = val;
}
-#endif // FEATURE_CORECLR || CROSSGEN_COMPILE
void Zapper::SetOutputFilename(LPCWSTR pwzOutputFilename)