summaryrefslogtreecommitdiff
path: root/src/vm/domainfile.h
diff options
context:
space:
mode:
authorJiyoung Yun <jy910.yun@samsung.com>2016-11-23 19:09:09 +0900
committerJiyoung Yun <jy910.yun@samsung.com>2016-11-23 19:09:09 +0900
commit4b4aad7217d3292650e77eec2cf4c198ea9c3b4b (patch)
tree98110734c91668dfdbb126fcc0e15ddbd93738ca /src/vm/domainfile.h
parentfa45f57ed55137c75ac870356a1b8f76c84b229c (diff)
downloadcoreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.tar.gz
coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.tar.bz2
coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.zip
Imported Upstream version 1.1.0upstream/1.1.0
Diffstat (limited to 'src/vm/domainfile.h')
-rw-r--r--src/vm/domainfile.h946
1 files changed, 946 insertions, 0 deletions
diff --git a/src/vm/domainfile.h b/src/vm/domainfile.h
new file mode 100644
index 0000000000..55a0907a0b
--- /dev/null
+++ b/src/vm/domainfile.h
@@ -0,0 +1,946 @@
+// 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.
+// --------------------------------------------------------------------------------
+// DomainFile.h
+//
+
+// --------------------------------------------------------------------------------
+
+
+#ifndef _DOMAINFILE_H_
+#define _DOMAINFILE_H_
+
+// --------------------------------------------------------------------------------
+// Required headers
+// --------------------------------------------------------------------------------
+
+// --------------------------------------------------------------------------------
+// Forward class declarations
+// --------------------------------------------------------------------------------
+class AppDomain;
+class DomainAssembly;
+class DomainModule;
+class Assembly;
+class Module;
+class DynamicMethodTable;
+struct AssemblyLoadSecurity;
+
+typedef VPTR(class IAssemblySecurityDescriptor) PTR_IAssemblySecurityDescriptor;
+
+enum FileLoadLevel
+{
+ // These states are tracked by FileLoadLock
+
+ // Note: This enum must match the static array fileLoadLevelName[]
+ // which contains the printable names of the enum values
+
+ // Note that semantics here are description is the LAST step done, not what is
+ // currently being done.
+
+ FILE_LOAD_CREATE,
+ FILE_LOAD_BEGIN,
+ FILE_LOAD_FIND_NATIVE_IMAGE,
+ FILE_LOAD_VERIFY_NATIVE_IMAGE_DEPENDENCIES,
+ FILE_LOAD_ALLOCATE,
+ FILE_LOAD_ADD_DEPENDENCIES,
+ FILE_LOAD_PRE_LOADLIBRARY,
+ FILE_LOAD_LOADLIBRARY,
+ FILE_LOAD_POST_LOADLIBRARY,
+ FILE_LOAD_EAGER_FIXUPS,
+ FILE_LOAD_VTABLE_FIXUPS,
+ FILE_LOAD_DELIVER_EVENTS,
+ FILE_LOADED, // Loaded by not yet active
+ FILE_LOAD_VERIFY_EXECUTION,
+ FILE_ACTIVE // Fully active (constructors run & security checked)
+};
+
+
+enum NotificationStatus
+{
+ NOT_NOTIFIED=0,
+ PROFILER_NOTIFIED=1,
+ DEBUGGER_NEEDNOTIFICATION=2,
+ DEBUGGER_NOTIFIED=4
+};
+
+// --------------------------------------------------------------------------------
+// DomainFile represents a file loaded (or being loaded) into an app domain. It
+// is guranteed to be unique per file per app domain.
+// --------------------------------------------------------------------------------
+
+class DomainFile
+{
+ VPTR_BASE_VTABLE_CLASS(DomainFile);
+
+ public:
+
+ // ------------------------------------------------------------
+ // Public API
+ // ------------------------------------------------------------
+
+#ifndef DACCESS_COMPILE
+ virtual ~DomainFile();
+ DomainFile() {LIMITED_METHOD_CONTRACT;};
+#endif
+
+ LoaderAllocator *GetLoaderAllocator();
+
+ PTR_AppDomain GetAppDomain()
+ {
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+ return m_pDomain;
+ }
+
+ PEFile *GetFile()
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+ return m_pFile;
+ }
+
+ PEFile *GetOriginalFile()
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+ return m_pOriginalFile!= NULL ? m_pOriginalFile : m_pFile;
+ }
+
+
+ IMDInternalImport *GetMDImport()
+ {
+ WRAPPER_NO_CONTRACT;
+ return m_pFile->GetPersistentMDImport();
+ }
+
+ OBJECTREF GetExposedModuleObjectIfExists()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ OBJECTREF objRet = NULL;
+ GET_LOADERHANDLE_VALUE_FAST(GetLoaderAllocator(), m_hExposedModuleObject, &objRet);
+ return objRet;
+ }
+
+ OBJECTREF GetExposedModuleObject();
+
+ BOOL IsSystem()
+ {
+ WRAPPER_NO_CONTRACT;
+ return GetFile()->IsSystem();
+ }
+
+ LPCUTF8 GetSimpleName()
+ {
+ WRAPPER_NO_CONTRACT;
+ return GetFile()->GetSimpleName();
+ }
+
+#ifdef LOGGING
+ LPCWSTR GetDebugName()
+ {
+ WRAPPER_NO_CONTRACT;
+ return GetFile()->GetDebugName();
+ }
+#endif
+
+#ifdef FEATURE_MIXEDMODE
+ LPVOID GetUMThunk(LPVOID pManagedIp, PCCOR_SIGNATURE pSig, ULONG cSig);
+#endif
+
+ void ReleaseFiles() DAC_EMPTY();
+
+ virtual BOOL IsAssembly() = 0;
+
+ DomainAssembly *GetDomainAssembly();
+
+ // ------------------------------------------------------------
+ // Loading state checks
+ // ------------------------------------------------------------
+
+ // Return the File's load level. Note that this is the last level actually successfully completed.
+ // Note that this is subtly different than the FileLoadLock's level, which is the last level
+ // which was triggered (but potentially skipped if error or inappropriate.)
+ FileLoadLevel GetLoadLevel() { LIMITED_METHOD_DAC_CONTRACT; return m_level; }
+
+ // Error means that a permanent x-appdomain load error has occurred.
+ BOOL IsError()
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+ DACCOP_IGNORE(FieldAccess, "No marshalling required");
+ return m_pError != NULL;
+ }
+
+ // Loading means that the load is still being tracked by a FileLoadLock.
+ BOOL IsLoading() { LIMITED_METHOD_CONTRACT; return m_loading; }
+
+ // Loaded means that the file can be used passively. This includes loading types, reflection, and
+ // jitting.
+ BOOL IsLoaded() { LIMITED_METHOD_DAC_CONTRACT; return m_level >= FILE_LOAD_DELIVER_EVENTS; }
+
+ // Active means that the file can be used actively in the current app domain. Note that a shared file
+ // may conditionally not be able to be made active on a per app domain basis.
+ BOOL IsActive() { LIMITED_METHOD_CONTRACT; return m_level >= FILE_ACTIVE; }
+
+ // Checks if the load has reached the point where profilers may be notified
+ // about the file. It's important that IF a profiler is notified, THEN this returns
+ // TRUE, otherwise there can be profiler-attach races where the profiler doesn't see
+ // the file via either enumeration or notification. As a result, this begins
+ // returning TRUE just before the profiler is actually notified. See
+ // code:ProfilerFunctionEnum::Init#ProfilerEnumAssemblies
+ BOOL IsAvailableToProfilers()
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+ return IsProfilerNotified(); // despite the name, this function returns TRUE just before we notify the profiler
+ }
+
+ // CheckLoaded is appropriate for asserts that the assembly can be passively used.
+ CHECK CheckLoaded();
+
+ // CheckActivated is appropriate for asserts that the assembly can be actively used. Note that
+ // it is slightly different from IsActive in that it deals with reentrancy cases properly.
+ CHECK CheckActivated();
+
+ // Ensure that an assembly has reached at least the IsLoaded state. Throw if not.
+ void EnsureLoaded()
+ {
+ WRAPPER_NO_CONTRACT;
+ return EnsureLoadLevel(FILE_LOADED);
+ }
+
+ // Ensure that an assembly has reached at least the IsActive state. Throw if not.
+ void EnsureActive()
+ {
+ WRAPPER_NO_CONTRACT;
+ return EnsureLoadLevel(FILE_ACTIVE);
+ }
+
+ // Ensure that an assembly has reached at least the Allocated state. Throw if not.
+ void EnsureAllocated()
+ {
+ WRAPPER_NO_CONTRACT;
+ return EnsureLoadLevel(FILE_LOAD_ALLOCATE);
+ }
+
+
+ void EnsureLibraryLoaded()
+ {
+ WRAPPER_NO_CONTRACT;
+ return EnsureLoadLevel(FILE_LOAD_LOADLIBRARY);
+ }
+
+ // This wraps EnsureActive, suppressing non-transient exceptions
+ BOOL TryEnsureActive();
+
+ // EnsureLoadLevel is a generic routine used to ensure that the file is not in a delay loaded
+ // state (unless it needs to be.) This should be used when a particular level of loading
+ // is required for an operation. Note that deadlocks are tolerated so the level may be one
+ void EnsureLoadLevel(FileLoadLevel targetLevel) DAC_EMPTY();
+
+ // AttemptLoadLevel is a generic routine used to try to further load the file to a given level.
+ // No guarantee is made about the load level resulting however.
+ void AttemptLoadLevel(FileLoadLevel targetLevel) DAC_EMPTY();
+
+ // CheckLoadLevel is an assert predicate used to verify the load level of an assembly.
+ // deadlockOK indicates that the level is allowed to be one short if we are restricted
+ // by loader reentrancy.
+ CHECK CheckLoadLevel(FileLoadLevel requiredLevel, BOOL deadlockOK = TRUE) DAC_EMPTY_RET(CHECK::OK());
+
+ // RequireLoadLevel throws an exception if the domain file isn't loaded enough. Note
+ // that this is intolerant of deadlock related failures so is only really appropriate for
+ // checks inside the main loading loop.
+ void RequireLoadLevel(FileLoadLevel targetLevel) DAC_EMPTY();
+
+ // Throws if a load error has occurred
+ void ThrowIfError(FileLoadLevel targetLevel) DAC_EMPTY();
+
+ // Checks that a load error has not occurred before the given level
+ CHECK CheckNoError(FileLoadLevel targetLevel) DAC_EMPTY_RET(CHECK::OK());
+
+ // IsNotified means that the profiler API notification has been delivered
+ BOOL IsProfilerNotified() { LIMITED_METHOD_CONTRACT; return m_notifyflags & PROFILER_NOTIFIED; }
+ BOOL IsDebuggerNotified() { LIMITED_METHOD_CONTRACT; return m_notifyflags & DEBUGGER_NOTIFIED; }
+ BOOL ShouldNotifyDebugger() { LIMITED_METHOD_CONTRACT; return m_notifyflags & DEBUGGER_NEEDNOTIFICATION; }
+
+
+ // ------------------------------------------------------------
+ // Other public APIs
+ // ------------------------------------------------------------
+
+ BOOL IsIntrospectionOnly();
+
+#ifndef DACCESS_COMPILE
+ BOOL Equals(DomainFile *pFile) { WRAPPER_NO_CONTRACT; return GetFile()->Equals(pFile->GetFile()); }
+ BOOL Equals(PEFile *pFile) { WRAPPER_NO_CONTRACT; return GetFile()->Equals(pFile); }
+#endif // DACCESS_COMPILE
+
+ Module* GetCurrentModule();
+ Module* GetLoadedModule();
+ Module* GetModule();
+
+#ifdef FEATURE_PREJIT
+ BOOL IsZapRequired(); // Are we absolutely required to use a native image?
+#endif
+ // The format string is intentionally unicode to avoid globalization bugs
+#ifdef FEATURE_PREJIT
+ void ExternalLog(DWORD level, const WCHAR *fmt, ...);
+ void ExternalLog(DWORD level, const char *msg);
+#endif
+#ifdef DACCESS_COMPILE
+ virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
+#endif
+
+#ifndef DACCESS_COMPILE
+ // light code gen. Keep the list of MethodTables needed for creating dynamic methods
+ DynamicMethodTable* GetDynamicMethodTable();
+#endif
+
+ protected:
+ // ------------------------------------------------------------
+ // Loader API
+ // ------------------------------------------------------------
+
+ friend class AppDomain;
+ friend class Assembly;
+ friend class Module;
+ friend class FileLoadLock;
+
+ DomainFile(AppDomain *pDomain, PEFile *pFile);
+
+ BOOL DoIncrementalLoad(FileLoadLevel targetLevel);
+ void ClearLoading() { LIMITED_METHOD_CONTRACT; m_loading = FALSE; }
+ void SetLoadLevel(FileLoadLevel level) { LIMITED_METHOD_CONTRACT; m_level = level; }
+
+#ifndef DACCESS_COMPILE
+ virtual void Begin() = 0;
+ virtual void Allocate() = 0;
+ void AddDependencies();
+ void PreLoadLibrary();
+ void LoadLibrary();
+ void PostLoadLibrary();
+ void EagerFixups();
+ void VtableFixups();
+ virtual void DeliverSyncEvents() = 0;
+ virtual void DeliverAsyncEvents() = 0;
+ void FinishLoad();
+ void VerifyExecution();
+ void Activate();
+#endif
+
+ // This is called when a new active dependency is added.
+ static BOOL PropagateNewActivation(Module *pModuleFrom, Module *pModuleTo);
+#ifdef FEATURE_LOADER_OPTIMIZATION
+ static BOOL PropagateActivationInAppDomain(Module *pModuleFrom, Module *pModuleTo, AppDomain* pDomain);
+#endif
+ // This can be used to verify that no propagation is needed
+ static CHECK CheckUnactivatedInAllDomains(Module *pModule);
+
+ // This should be used to permanently set the load to fail. Do not use with transient conditions
+ void SetError(Exception *ex);
+
+#ifdef FEATURE_PREJIT
+
+#ifndef DACCESS_COMPILE
+ virtual void FindNativeImage() = 0;
+#endif
+ void VerifyNativeImageDependencies(bool verifyOnly = FALSE);
+
+ // Are we absolutely required to use a native image?
+ void CheckZapRequired();
+
+ void ClearNativeImageStress();
+
+#endif // FEATURE_PREJIT
+
+ void SetProfilerNotified() { LIMITED_METHOD_CONTRACT; m_notifyflags|= PROFILER_NOTIFIED; }
+ void SetDebuggerNotified() { LIMITED_METHOD_CONTRACT; m_notifyflags|=DEBUGGER_NOTIFIED; }
+ void SetShouldNotifyDebugger() { LIMITED_METHOD_CONTRACT; m_notifyflags|=DEBUGGER_NEEDNOTIFICATION; }
+#ifndef DACCESS_COMPILE
+ void UpdatePEFileWorker(PTR_PEFile pFile);
+#endif
+
+ // ------------------------------------------------------------
+ // Instance data
+ // ------------------------------------------------------------
+
+ PTR_AppDomain m_pDomain;
+ PTR_PEFile m_pFile;
+ PTR_PEFile m_pOriginalFile; // keep file alive just in case someone is sitill using it. If this is not NULL then m_pFile contains reused file from the shared assembly
+ PTR_Module m_pModule;
+ FileLoadLevel m_level;
+ LOADERHANDLE m_hExposedModuleObject;
+
+ class ExInfo
+ {
+ enum
+ {
+ ExType_ClrEx,
+ ExType_HR
+ }
+ m_type;
+ union
+ {
+ Exception *m_pEx;
+ HRESULT m_hr;
+ };
+
+ public:
+ void Throw()
+ {
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+ if (m_type==ExType_ClrEx)
+ {
+ PAL_CPP_THROW(Exception *, m_pEx->DomainBoundClone());
+ }
+ if (m_type==ExType_HR)
+ ThrowHR(m_hr);
+ _ASSERTE(!"Bad exception type");
+ ThrowHR(E_UNEXPECTED);
+ };
+ ExInfo(Exception* pEx)
+ {
+ LIMITED_METHOD_CONTRACT;
+ m_type=ExType_ClrEx;
+ m_pEx=pEx;
+ };
+
+ void ConvertToHResult()
+ {
+ LIMITED_METHOD_CONTRACT;
+ if(m_type==ExType_HR)
+ return;
+ _ASSERTE(m_type==ExType_ClrEx);
+ HRESULT hr=m_pEx->GetHR();
+ delete m_pEx;
+ m_hr=hr;
+ m_type=ExType_HR;
+ };
+ ~ExInfo()
+ {
+ LIMITED_METHOD_CONTRACT;
+ if (m_type==ExType_ClrEx)
+ delete m_pEx;
+ }
+ }* m_pError;
+
+ void ReleaseManagedData()
+ {
+ if (m_pError)
+ m_pError->ConvertToHResult();
+ };
+
+#ifdef FEATURE_PREJIT
+ // Lock-free enumeration of DomainFiles in an AppDomain.
+public:
+ DomainFile *FindNextDomainFileWithNativeImage();
+private:
+ void InsertIntoDomainFileWithNativeImageList();
+#endif // FEATURE_PREJIT
+
+ DWORD m_notifyflags;
+ BOOL m_loading;
+ // m_pDynamicMethodTable is used by the light code generation to allow method
+ // generation on the fly. They are lazily created when/if a dynamic method is requested
+ // for this specific module
+ DynamicMethodTable *m_pDynamicMethodTable;
+ class UMThunkHash *m_pUMThunkHash;
+ BOOL m_bDisableActivationCheck;
+
+ // This value is to make it easier to diagnose Assembly Loader "rejected native image" crashes.
+ // See Dev11 bug 358184 for more details
+public:
+ DWORD m_dwReasonForRejectingNativeImage; // See code:g_dwLoaderReasonForNotSharing in Assembly.cpp for a similar variable.
+private:
+
+#ifdef FEATURE_PREJIT
+ // This value is to allow lock-free enumeration of all native images in an AppDomain
+ Volatile<DomainFile *> m_pNextDomainFileWithNativeImage;
+#endif
+};
+
+// These will sometimes result in a crash with error code 0x80131506 COR_E_EXECUTIONENGINE
+// "An internal error happened in the Common Language Runtime's Execution Engine"
+// Cause: Incorrectly committed to using native image for <path to assembly>
+enum ReasonForRejectingNativeImage
+{
+ ReasonForRejectingNativeImage_NoNiForManifestModule = 0x101,
+ ReasonForRejectingNativeImage_DependencyNotNative = 0x102,
+ ReasonForRejectingNativeImage_MscorlibNotNative = 0x103,
+ ReasonForRejectingNativeImage_FailedSecurityCheck = 0x104,
+ ReasonForRejectingNativeImage_DependencyIdentityMismatch = 0x105,
+ ReasonForRejectingNativeImage_CannotShareNiAssemblyNotDomainNeutral = 0x106,
+ ReasonForRejectingNativeImage_NiAlreadyUsedInAnotherSharedAssembly = 0x107,
+};
+
+//---------------------------------------------------------------------------------------
+// One of these values is specified when requesting a module iterator to customize which
+// modules should appear in the enumeration
+enum ModuleIterationOption
+{
+ // include only modules that are already loaded (m_level >= FILE_LOAD_DELIVER_EVENTS)
+ kModIterIncludeLoaded = 1,
+
+ // include all modules, even those that are still in the process of loading (all m_level values)
+ kModIterIncludeLoading = 2,
+
+ // include only modules loaded just enough that profilers are notified of them.
+ // (m_level >= FILE_LOAD_LOADLIBRARY). See comment at code:DomainFile::IsAvailableToProfilers
+ kModIterIncludeAvailableToProfilers = 3,
+};
+
+
+enum CMD_State
+{
+ CMD_Unknown,
+ CMD_NotNeeded,
+ CMD_IndeedMissing,
+ CMD_Resolved
+};
+
+// --------------------------------------------------------------------------------
+// DomainAssembly is a subclass of DomainFile which specifically represents a assembly.
+// --------------------------------------------------------------------------------
+
+class DomainAssembly : public DomainFile
+{
+ VPTR_VTABLE_CLASS(DomainAssembly, DomainFile);
+
+public:
+ // ------------------------------------------------------------
+ // Public API
+ // ------------------------------------------------------------
+
+ PEAssembly *GetFile()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return PTR_PEAssembly(m_pFile);
+ }
+
+#ifdef FEATURE_FUSION
+ IAssemblyBindingClosure* GetAssemblyBindingClosure(WALK_LEVEL level);
+ BOOL IsClosedInGAC();
+ BOOL MayHaveUnknownDependencies();
+#endif
+
+ // Returns security information for the assembly based on the codebase
+ void GetSecurityIdentity(SString &codebase, SecZone *pdwZone, DWORD dwFlags, BYTE *pbUniqueID, DWORD *pcbUniqueID);
+
+ IAssemblySecurityDescriptor* GetSecurityDescriptor()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return static_cast<IAssemblySecurityDescriptor*>(m_pSecurityDescriptor);
+ }
+#ifdef FEATURE_LOADER_OPTIMIZATION
+
+#ifdef FEATURE_FUSION
+private:
+ enum CMDI_Result
+ {
+ CMDI_End,
+ CMDI_AssemblyResolveSucceeded,
+ CMDI_AssemblyResolveFailed
+ };
+
+ CMDI_Result CheckMissingDependencyInner(IAssemblyBindingClosure* pClosure, DWORD idx);
+
+
+#endif
+public:
+ CMD_State CheckMissingDependencies();
+ BOOL MissingDependenciesCheckDone();
+#endif // FEATURE_LOADER_OPTIMIZATION
+
+#ifndef DACCESS_COMPILE
+#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
+ DomainFile *FindModule(PEFile *pFile, BOOL includeLoading = FALSE);
+ DomainModule *FindModule(PEModule *pFile, BOOL includeLoading = FALSE)
+ {
+ WRAPPER_NO_CONTRACT;
+ return (DomainModule *) FindModule((PEFile *) pFile, includeLoading);
+ }
+#endif // FEATURE_MULTIMODULE_ASSEMBLIES
+ void ReleaseFiles();
+#endif // DACCESS_COMPILE
+
+ // Finds only loaded hmods
+ DomainFile *FindIJWModule(HMODULE hMod);
+
+ void SetAssembly(Assembly* pAssembly);
+
+ BOOL IsAssembly()
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+ return TRUE;
+ }
+
+ OBJECTREF GetExposedAssemblyObjectIfExists()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ OBJECTREF objRet = NULL;
+ GET_LOADERHANDLE_VALUE_FAST(GetLoaderAllocator(), m_hExposedAssemblyObject, &objRet);
+ return objRet;
+ }
+
+ // Returns managed representation of the assembly (Assembly or AssemblyBuilder).
+ // Returns NULL if the managed scout was already collected (see code:LoaderAllocator#AssemblyPhases).
+ OBJECTREF GetExposedAssemblyObject();
+
+ Assembly* GetCurrentAssembly();
+ Assembly* GetLoadedAssembly();
+ Assembly* GetAssembly();
+
+#ifdef DACCESS_COMPILE
+ virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
+#endif
+
+ // ------------------------------------------------------------
+ // Modules
+ // ------------------------------------------------------------
+ class ModuleIterator
+ {
+ ArrayList::Iterator m_i;
+ ModuleIterationOption m_moduleIterationOption;
+
+ public:
+ BOOL Next()
+ {
+ WRAPPER_NO_CONTRACT;
+ while (m_i.Next())
+ {
+ if (m_i.GetElement() == NULL)
+ {
+ continue;
+ }
+ if (GetDomainFile()->IsError())
+ {
+ continue;
+ }
+ if (m_moduleIterationOption == kModIterIncludeLoading)
+ return TRUE;
+ if ((m_moduleIterationOption == kModIterIncludeLoaded) &&
+ GetDomainFile()->IsLoaded())
+ return TRUE;
+ if ((m_moduleIterationOption == kModIterIncludeAvailableToProfilers) &&
+ GetDomainFile()->IsAvailableToProfilers())
+ return TRUE;
+ }
+ return FALSE;
+ }
+ Module *GetModule()
+ {
+ WRAPPER_NO_CONTRACT;
+ return GetDomainFile()->GetModule();
+ }
+ Module *GetLoadedModule()
+ {
+ WRAPPER_NO_CONTRACT;
+ return GetDomainFile()->GetLoadedModule();
+ }
+ DomainFile *GetDomainFile()
+ {
+ WRAPPER_NO_CONTRACT;
+ return dac_cast<PTR_DomainFile>(m_i.GetElement());
+ }
+ SIZE_T GetIndex()
+ {
+ WRAPPER_NO_CONTRACT;
+ return m_i.GetIndex();
+ }
+
+ private:
+ friend class DomainAssembly;
+ // Cannot have constructor so this iterator can be used inside a union
+ static ModuleIterator Create(DomainAssembly * pDomainAssembly, ModuleIterationOption moduleIterationOption)
+ {
+ WRAPPER_NO_CONTRACT;
+ ModuleIterator i;
+
+ i.m_i = pDomainAssembly->m_Modules.Iterate();
+ i.m_moduleIterationOption = moduleIterationOption;
+
+ return i;
+ }
+ };
+ friend class ModuleIterator;
+
+ ModuleIterator IterateModules(ModuleIterationOption moduleIterationOption)
+ {
+ WRAPPER_NO_CONTRACT;
+ return ModuleIterator::Create(this, moduleIterationOption);
+ }
+
+ DomainFile *LookupDomainFile(DWORD index)
+ {
+ WRAPPER_NO_CONTRACT;
+ if (index >= m_Modules.GetCount())
+ return NULL;
+ else
+ return dac_cast<PTR_DomainFile>(m_Modules.Get(index));
+ }
+
+ Module *LookupModule(DWORD index)
+ {
+ WRAPPER_NO_CONTRACT;
+ DomainFile *pModule = LookupDomainFile(index);
+ if (pModule == NULL)
+ return NULL;
+ else
+ return pModule->GetModule();
+ }
+
+#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
+ void AddModule(DomainModule *pModule);
+#endif // FEATURE_MULTIMODULE_ASSEMBLIES
+
+ // ------------------------------------------------------------
+ // Resource access
+ // ------------------------------------------------------------
+
+ BOOL GetResource(LPCSTR szName, DWORD *cbResource,
+ PBYTE *pbInMemoryResource, DomainAssembly** pAssemblyRef,
+ LPCSTR *szFileName, DWORD *dwLocation,
+ StackCrawlMark *pStackMark, BOOL fSkipSecurityCheck,
+ BOOL fSkipRaiseResolveEvent);
+
+#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
+ BOOL GetModuleResource(mdFile mdResFile, LPCSTR szResName,
+ DWORD *cbResource, PBYTE *pbInMemoryResource,
+ LPCSTR *szFileName, DWORD *dwLocation,
+ BOOL fIsPublic, StackCrawlMark *pStackMark,
+ BOOL fSkipSecurityCheck);
+#endif // FEATURE_MULTIMODULE_ASSEMBLIES
+#ifdef FEATURE_PREJIT
+ // ------------------------------------------------------------
+ // Prejitting API
+ // ------------------------------------------------------------
+
+ void GetCurrentVersionInfo(CORCOMPILE_VERSION_INFO *pZapVersionInfo);
+
+ void GetOptimizedIdentitySignature(CORCOMPILE_ASSEMBLY_SIGNATURE *pSignature);
+ BOOL CheckZapDependencyIdentities(PEImage *pNativeImage);
+ BOOL CheckZapSecurity(PEImage *pNativeImage);
+
+ BOOL CheckFileSystemTimeStamps(PEFile *pZapManifest);
+
+#endif // FEATURE_PREJIT
+
+ // ------------------------------------------------------------
+ // Debugger control API
+ // ------------------------------------------------------------
+
+ DebuggerAssemblyControlFlags GetDebuggerInfoBits(void)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_debuggerFlags;
+ }
+
+ void SetDebuggerInfoBits(DebuggerAssemblyControlFlags newBits)
+ {
+ LIMITED_METHOD_CONTRACT;
+ m_debuggerFlags = newBits;
+ }
+
+ void SetupDebuggingConfig(void);
+ DWORD ComputeDebuggingConfig(void);
+
+ bool GetDebuggingOverrides(DWORD *pdwFlags);
+
+ HRESULT GetDebuggingCustomAttributes(DWORD *pdwFlags);
+
+ BOOL IsVisibleToDebugger();
+ BOOL NotifyDebuggerLoad(int flags, BOOL attaching);
+ void NotifyDebuggerUnload();
+ BOOL IsUnloading();
+
+ inline BOOL IsCollectible();
+ //
+ // GC API
+ //
+ void EnumStaticGCRefs(promote_func* fn, ScanContext* sc);
+
+
+ private:
+
+ // ------------------------------------------------------------
+ // Loader API
+ // ------------------------------------------------------------
+
+ friend class AppDomain;
+ friend class Assembly;
+ friend class AssemblyNameNative;
+
+#ifndef DACCESS_COMPILE
+public:
+ ~DomainAssembly();
+private:
+ DomainAssembly(AppDomain *pDomain, PEFile *pFile, AssemblyLoadSecurity *pLoadSecurity, LoaderAllocator *pLoaderAllocator);
+#endif
+
+ // ------------------------------------------------------------
+ // Internal routines
+ // ------------------------------------------------------------
+
+ void SetSecurityError(Exception *ex);
+
+#ifndef DACCESS_COMPILE
+ void Begin();
+ void Allocate();
+ void LoadSharers();
+ void DeliverSyncEvents();
+ void DeliverAsyncEvents();
+#endif
+
+ void UpdatePEFile(PTR_PEFile pFile);
+
+#ifdef FEATURE_PREJIT
+#ifndef DACCESS_COMPILE
+ void FindNativeImage();
+#endif
+#endif // FEATURE_PREJIT
+
+ BOOL IsInstrumented();
+
+ public:
+ 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();
+ BOOL ShouldSkipPolicyResolution();
+
+ // ------------------------------------------------------------
+ // Instance data
+ // ------------------------------------------------------------
+
+ private:
+ LOADERHANDLE m_hExposedAssemblyObject;
+ PTR_IAssemblySecurityDescriptor m_pSecurityDescriptor;
+ PTR_Assembly m_pAssembly;
+ DebuggerAssemblyControlFlags m_debuggerFlags;
+#ifdef FEATURE_FUSION
+ ReleaseHolder<IAssemblyBindingClosure> m_pAssemblyBindingClosure;
+#endif
+ CMD_State m_MissingDependenciesCheckStatus;
+ ArrayList m_Modules;
+ BOOL m_fSkipPolicyResolution;
+ BOOL m_fDebuggerUnloadStarted;
+ BOOL m_fCollectible;
+ Volatile<bool> m_fHostAssemblyPublished;
+ Volatile<bool> m_fCalculatedShouldLoadDomainNeutral;
+ Volatile<bool> m_fShouldLoadDomainNeutral;
+
+ public:
+ // Indicates if the assembly can be cached in a binding cache such as AssemblySpecBindingCache.
+ inline bool CanUseWithBindingCache()
+ { STATIC_CONTRACT_WRAPPER; return GetFile()->CanUseWithBindingCache(); }
+};
+
+typedef DomainAssembly::ModuleIterator DomainModuleIterator;
+
+// --------------------------------------------------------------------------------
+// DomainModule is a subclass of DomainFile which specifically represents a module.
+// --------------------------------------------------------------------------------
+#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
+
+class DomainModule : public DomainFile
+{
+ VPTR_VTABLE_CLASS(DomainModule, DomainFile);
+
+ private:
+ PTR_DomainAssembly m_pDomainAssembly;
+
+ void UpdatePEFile(PTR_PEFile pFile);
+
+ public:
+
+ // ------------------------------------------------------------
+ // Public API
+ // ------------------------------------------------------------
+
+ DomainAssembly *GetDomainAssembly()
+ {
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+ return m_pDomainAssembly;
+ }
+
+ Module *GetModule()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ return m_pModule;
+ }
+
+ LPCSTR GetName()
+ {
+ WRAPPER_NO_CONTRACT;
+ return GetFile()->GetSimpleName();
+ }
+
+ mdFile GetToken()
+ {
+ WRAPPER_NO_CONTRACT;
+ return GetFile()->GetToken();
+ }
+
+ PEModule *GetFile()
+ {
+ WRAPPER_NO_CONTRACT;
+ return PTR_PEModule(m_pFile);
+ }
+
+ BOOL IsAssembly()
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+ return FALSE;
+ }
+
+ void SetModule(Module *pModule);
+
+#ifdef DACCESS_COMPILE
+ virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
+#endif
+
+ // ------------------------------------------------------------
+ // Loader API
+ // ------------------------------------------------------------
+
+ friend class COMModule;
+
+#ifndef DACCESS_COMPILE
+ DomainModule(AppDomain *pDomain, DomainAssembly *pAssembly, PEFile *pFile);
+ ~DomainModule();
+#endif
+
+ // ------------------------------------------------------------
+ // Internal routines
+ // ------------------------------------------------------------
+
+#ifndef DACCESS_COMPILE
+ void Begin();
+ void Allocate();
+ void LoadSharers();
+ void DeliverSyncEvents();
+ void DeliverAsyncEvents();
+#endif
+
+#ifdef FEATURE_PREJIT
+#ifndef DACCESS_COMPILE
+ void FindNativeImage();
+#endif
+#endif // FEATURE_PREJIT
+};
+#endif // FEATURE_MULTIMODULE_ASSEMBLIES
+#endif // _DOMAINFILE_H_