1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | /*============================================================ |
6 | ** |
7 | ** Header: Assembly.hpp |
8 | ** |
9 | |
10 | ** |
11 | ** Purpose: Implements assembly (loader domain) architecture |
12 | ** |
13 | ** |
14 | ===========================================================*/ |
15 | #ifndef _ASSEMBLY_H |
16 | #define _ASSEMBLY_H |
17 | |
18 | #include "ceeload.h" |
19 | #include "exceptmacros.h" |
20 | #include "clsload.hpp" |
21 | #include "eehash.h" |
22 | #include "listlock.h" |
23 | #include "iceefilegen.h" |
24 | #include "cordbpriv.h" |
25 | #include "assemblyspec.hpp" |
26 | |
27 | // A helper macro for the assembly's module hash (m_pAllowedFiles). |
28 | #define UTF8_TO_LOWER_CASE(str, qb) \ |
29 | { \ |
30 | WRAPPER_NO_CONTRACT; \ |
31 | INT32 allocBytes = InternalCasingHelper::InvariantToLower(NULL, 0, str); \ |
32 | qb.AllocThrows(allocBytes); \ |
33 | InternalCasingHelper::InvariantToLower((LPUTF8) qb.Ptr(), allocBytes, str); \ |
34 | } |
35 | |
36 | |
37 | class BaseDomain; |
38 | class AppDomain; |
39 | class DomainAssembly; |
40 | class DomainModule; |
41 | class SystemDomain; |
42 | class ClassLoader; |
43 | class ComDynamicWrite; |
44 | class AssemblySink; |
45 | class AssemblyNative; |
46 | class AssemblySpec; |
47 | class ISharedSecurityDescriptor; |
48 | class SecurityTransparencyBehavior; |
49 | class Pending; |
50 | class AllocMemTracker; |
51 | class FriendAssemblyDescriptor; |
52 | |
53 | // Bits in m_dwDynamicAssemblyAccess (see System.Reflection.Emit.AssemblyBuilderAccess.cs) |
54 | #define ASSEMBLY_ACCESS_RUN 0x01 |
55 | #define ASSEMBLY_ACCESS_SAVE 0x02 |
56 | #define ASSEMBLY_ACCESS_COLLECT 0x8 |
57 | |
58 | struct CreateDynamicAssemblyArgsGC |
59 | { |
60 | ASSEMBLYNAMEREF assemblyName; |
61 | LOADERALLOCATORREF loaderAllocator; |
62 | }; |
63 | |
64 | struct CreateDynamicAssemblyArgs : CreateDynamicAssemblyArgsGC |
65 | { |
66 | INT32 access; |
67 | StackCrawlMark* stackMark; |
68 | }; |
69 | |
70 | // An assembly is the unit of deployment for managed code. Typically Assemblies are one to one with files |
71 | // (Modules), however this is not necessary, as an assembly can contain serveral files (typically you only |
72 | // do this so that you can resource-only modules that are national language specific) |
73 | // |
74 | // Conceptually Assemblies are loaded into code:AppDomain |
75 | // |
76 | // So in general an assemly is a list of code:Module, where a code:Module is 1-1 with a DLL or EXE file. |
77 | // |
78 | // One of the modules the code:Assembly.m_pManifest is special in that it knows about all the other |
79 | // modules in an assembly (often it is the only one). |
80 | // |
81 | class Assembly |
82 | { |
83 | friend class BaseDomain; |
84 | friend class SystemDomain; |
85 | friend class ClassLoader; |
86 | friend class AssemblyNative; |
87 | friend class AssemblySpec; |
88 | friend class NDirect; |
89 | friend class AssemblyNameNative; |
90 | friend class ClrDataAccess; |
91 | |
92 | public: |
93 | Assembly(BaseDomain *pDomain, PEAssembly *pFile, DebuggerAssemblyControlFlags debuggerFlags, BOOL fIsCollectible); |
94 | void Init(AllocMemTracker *pamTracker, LoaderAllocator *pLoaderAllocator); |
95 | |
96 | void StartUnload(); |
97 | void Terminate( BOOL signalProfiler = TRUE ); |
98 | |
99 | static Assembly *Create(BaseDomain *pDomain, PEAssembly *pFile, DebuggerAssemblyControlFlags debuggerFlags, BOOL fIsCollectible, AllocMemTracker *pamTracker, LoaderAllocator *pLoaderAllocator); |
100 | |
101 | BOOL IsSystem() { WRAPPER_NO_CONTRACT; return m_pManifestFile->IsSystem(); } |
102 | |
103 | static Assembly *CreateDynamic(AppDomain *pDomain, CreateDynamicAssemblyArgs *args); |
104 | |
105 | MethodDesc *GetEntryPoint(); |
106 | |
107 | //**************************************************************************************** |
108 | // |
109 | // Additional init tasks for Modules. This should probably be part of Module::Initialize() |
110 | // but there's at least one call to ReflectionModule::Create that is *not* followed by a |
111 | // PrepareModule call. |
112 | void PrepareModuleForAssembly(Module* module, AllocMemTracker *pamTracker); |
113 | |
114 | // This is the final step of publishing a Module into an Assembly. This step cannot fail. |
115 | void PublishModuleIntoAssembly(Module *module); |
116 | |
117 | #ifndef DACCESS_COMPILE |
118 | void SetIsTenured() |
119 | { |
120 | WRAPPER_NO_CONTRACT; |
121 | m_pManifest->SetIsTenured(); |
122 | } |
123 | |
124 | // CAUTION: This should only be used as backout code if an assembly is unsuccessfully |
125 | // added to the shared domain assembly map. |
126 | void UnsetIsTenured() |
127 | { |
128 | WRAPPER_NO_CONTRACT; |
129 | m_pManifest->UnsetIsTenured(); |
130 | } |
131 | #endif // DACCESS_COMPILE |
132 | |
133 | //**************************************************************************************** |
134 | // |
135 | // Returns the class loader associated with the assembly. |
136 | ClassLoader* GetLoader() |
137 | { |
138 | LIMITED_METHOD_CONTRACT; |
139 | SUPPORTS_DAC; |
140 | return m_pClassLoader; |
141 | } |
142 | |
143 | // ------------------------------------------------------------ |
144 | // Modules |
145 | // ------------------------------------------------------------ |
146 | |
147 | class ModuleIterator |
148 | { |
149 | Module* m_pManifest; |
150 | DWORD m_i; |
151 | |
152 | public: |
153 | // The preferred constructor. If you use this, you don't have to |
154 | // call Start() yourself |
155 | ModuleIterator(Assembly *pAssembly) |
156 | { |
157 | WRAPPER_NO_CONTRACT; |
158 | Start(pAssembly); |
159 | } |
160 | |
161 | // When you don't have the Assembly at contruction time, use this |
162 | // constructor, and explicitly call Start() to begin the iteration. |
163 | ModuleIterator() |
164 | { |
165 | LIMITED_METHOD_CONTRACT; |
166 | SUPPORTS_DAC; |
167 | |
168 | m_pManifest = NULL; |
169 | m_i = (DWORD) -1; |
170 | } |
171 | |
172 | void Start(Assembly * pAssembly) |
173 | { |
174 | LIMITED_METHOD_CONTRACT; |
175 | SUPPORTS_DAC; |
176 | |
177 | m_pManifest = pAssembly->GetManifestModule(); |
178 | m_i = (DWORD) -1; |
179 | } |
180 | |
181 | BOOL Next() |
182 | { |
183 | LIMITED_METHOD_CONTRACT; |
184 | SUPPORTS_DAC; |
185 | while (++m_i <= m_pManifest->GetFileMax()) |
186 | { |
187 | if (GetModule() != NULL) |
188 | return TRUE; |
189 | } |
190 | return FALSE; |
191 | } |
192 | |
193 | Module *GetModule() |
194 | { |
195 | LIMITED_METHOD_CONTRACT; |
196 | SUPPORTS_DAC; |
197 | return m_pManifest->LookupFile(TokenFromRid(m_i, mdtFile)); |
198 | } |
199 | }; |
200 | |
201 | ModuleIterator IterateModules() |
202 | { |
203 | WRAPPER_NO_CONTRACT; |
204 | SUPPORTS_DAC; |
205 | return ModuleIterator(this); |
206 | } |
207 | |
208 | |
209 | //**************************************************************************************** |
210 | // |
211 | // Get the domain the assembly lives in. |
212 | PTR_BaseDomain Parent() |
213 | { |
214 | LIMITED_METHOD_CONTRACT; |
215 | return m_pDomain; |
216 | } |
217 | |
218 | // Sets the assemblies domain. |
219 | void SetParent(BaseDomain* pParent); |
220 | |
221 | //----------------------------------------------------------------------------------------- |
222 | // EnsureActive ensures that the assembly is properly prepped in the current app domain |
223 | // for active uses like code execution, static field access, and instance allocation |
224 | //----------------------------------------------------------------------------------------- |
225 | #ifndef DACCESS_COMPILE |
226 | VOID EnsureActive(); |
227 | #endif |
228 | |
229 | //----------------------------------------------------------------------------------------- |
230 | // CheckActivated is a check predicate which should be used in active use paths like code |
231 | // execution, static field access, and instance allocation |
232 | //----------------------------------------------------------------------------------------- |
233 | CHECK CheckActivated(); |
234 | |
235 | // Returns the parent domain if it is not the system area. Returns NULL if it is the |
236 | // system domain |
237 | PTR_BaseDomain GetDomain(); |
238 | PTR_LoaderAllocator GetLoaderAllocator() { LIMITED_METHOD_DAC_CONTRACT; return m_pLoaderAllocator; } |
239 | |
240 | BOOL GetModuleZapFile(LPCWSTR name, SString &path); |
241 | |
242 | #ifdef LOGGING |
243 | LPCWSTR GetDebugName() |
244 | { |
245 | WRAPPER_NO_CONTRACT; |
246 | return GetManifestFile()->GetDebugName(); |
247 | } |
248 | #endif |
249 | |
250 | LPCUTF8 GetSimpleName() |
251 | { |
252 | WRAPPER_NO_CONTRACT; |
253 | return GetManifestFile()->GetSimpleName(); |
254 | } |
255 | |
256 | BOOL IsStrongNamed() |
257 | { |
258 | WRAPPER_NO_CONTRACT; |
259 | return GetManifestFile()->IsStrongNamed(); |
260 | } |
261 | |
262 | const void *GetPublicKey(DWORD *pcbPK) |
263 | { |
264 | WRAPPER_NO_CONTRACT; |
265 | return GetManifestFile()->GetPublicKey(pcbPK); |
266 | } |
267 | |
268 | ULONG GetHashAlgId() |
269 | { |
270 | WRAPPER_NO_CONTRACT; |
271 | return GetManifestFile()->GetHashAlgId(); |
272 | } |
273 | |
274 | HRESULT GetVersion(USHORT *pMajor, USHORT *pMinor, USHORT *pBuild, USHORT *pRevision) |
275 | { |
276 | WRAPPER_NO_CONTRACT; |
277 | return GetManifestFile()->GetVersion(pMajor, pMinor, pBuild, pRevision); |
278 | } |
279 | |
280 | LPCUTF8 GetLocale() |
281 | { |
282 | WRAPPER_NO_CONTRACT; |
283 | return GetManifestFile()->GetLocale(); |
284 | } |
285 | |
286 | DWORD GetFlags() |
287 | { |
288 | WRAPPER_NO_CONTRACT; |
289 | return GetManifestFile()->GetFlags(); |
290 | } |
291 | |
292 | PTR_LoaderHeap GetLowFrequencyHeap(); |
293 | PTR_LoaderHeap GetHighFrequencyHeap(); |
294 | PTR_LoaderHeap GetStubHeap(); |
295 | |
296 | PTR_Module GetManifestModule() |
297 | { |
298 | LIMITED_METHOD_CONTRACT; |
299 | SUPPORTS_DAC; |
300 | return m_pManifest; |
301 | } |
302 | |
303 | PTR_PEAssembly GetManifestFile() |
304 | { |
305 | LIMITED_METHOD_CONTRACT; |
306 | SUPPORTS_DAC; |
307 | return m_pManifestFile; |
308 | } |
309 | |
310 | IMDInternalImport* GetManifestImport() |
311 | { |
312 | WRAPPER_NO_CONTRACT; |
313 | SUPPORTS_DAC; |
314 | return m_pManifestFile->GetPersistentMDImport(); |
315 | } |
316 | |
317 | #ifndef DACCESS_COMPILE |
318 | IMetaDataAssemblyImport* GetManifestAssemblyImporter() |
319 | { |
320 | WRAPPER_NO_CONTRACT; |
321 | return m_pManifestFile->GetAssemblyImporter(); |
322 | } |
323 | #endif // DACCESS_COMPILE |
324 | |
325 | mdAssembly GetManifestToken() |
326 | { |
327 | LIMITED_METHOD_CONTRACT; |
328 | |
329 | return TokenFromRid(1, mdtAssembly); |
330 | } |
331 | |
332 | #ifndef DACCESS_COMPILE |
333 | void GetDisplayName(SString &result, DWORD flags = 0) |
334 | { |
335 | WRAPPER_NO_CONTRACT; |
336 | |
337 | return m_pManifestFile->GetDisplayName(result, flags); |
338 | } |
339 | #endif // DACCESS_COMPILE |
340 | |
341 | void GetCodeBase(SString &result) |
342 | { |
343 | WRAPPER_NO_CONTRACT; |
344 | |
345 | return m_pManifestFile->GetCodeBase(result); |
346 | } |
347 | |
348 | OBJECTREF GetExposedObject(); |
349 | |
350 | DebuggerAssemblyControlFlags GetDebuggerInfoBits(void) |
351 | { |
352 | LIMITED_METHOD_CONTRACT; |
353 | |
354 | return m_debuggerFlags; |
355 | } |
356 | |
357 | void SetDebuggerInfoBits(DebuggerAssemblyControlFlags flags) |
358 | { |
359 | LIMITED_METHOD_CONTRACT; |
360 | |
361 | m_debuggerFlags = flags; |
362 | } |
363 | |
364 | void SetCopiedPDBs() |
365 | { |
366 | LIMITED_METHOD_CONTRACT; |
367 | |
368 | m_debuggerFlags = (DebuggerAssemblyControlFlags) (m_debuggerFlags | DACF_PDBS_COPIED); |
369 | } |
370 | |
371 | ULONG HashIdentity() |
372 | { |
373 | return GetManifestFile()->HashIdentity(); |
374 | } |
375 | |
376 | BOOL IsDisabledPrivateReflection(); |
377 | |
378 | //**************************************************************************************** |
379 | // |
380 | // Uses the given token to load a module or another assembly. Returns the module in |
381 | // which the implementation resides. |
382 | |
383 | mdFile GetManifestFileToken(IMDInternalImport *pImport, mdFile kFile); |
384 | mdFile GetManifestFileToken(LPCSTR name); |
385 | |
386 | // On failure: |
387 | // if loadFlag == Loader::Load => throw |
388 | // if loadFlag != Loader::Load => return NULL |
389 | Module *FindModuleByExportedType(mdExportedType mdType, |
390 | Loader::LoadFlag loadFlag, |
391 | mdTypeDef mdNested, |
392 | mdTypeDef *pCL); |
393 | |
394 | static Module * FindModuleByTypeRef(Module * pModule, |
395 | mdTypeRef typeRef, |
396 | Loader::LoadFlag loadFlag, |
397 | BOOL * pfNoResolutionScope); |
398 | |
399 | Module *FindModuleByName(LPCSTR moduleName); |
400 | |
401 | //**************************************************************************************** |
402 | // |
403 | INT32 ExecuteMainMethod(PTRARRAYREF *stringArgs, BOOL waitForOtherThreads); |
404 | |
405 | //**************************************************************************************** |
406 | |
407 | Assembly(); |
408 | ~Assembly(); |
409 | #ifdef FEATURE_PREJIT |
410 | void DeleteNativeCodeRanges(); |
411 | #endif |
412 | |
413 | BOOL GetResource(LPCSTR szName, DWORD *cbResource, |
414 | PBYTE *pbInMemoryResource, Assembly **pAssemblyRef, |
415 | LPCSTR *szFileName, DWORD *dwLocation, |
416 | BOOL fSkipRaiseResolveEvent = FALSE); |
417 | |
418 | //**************************************************************************************** |
419 | #ifdef DACCESS_COMPILE |
420 | void EnumMemoryRegions(CLRDataEnumMemoryFlags flags); |
421 | #endif |
422 | |
423 | FORCEINLINE BOOL IsDynamic() { LIMITED_METHOD_CONTRACT; return m_isDynamic; } |
424 | FORCEINLINE BOOL IsCollectible() { LIMITED_METHOD_DAC_CONTRACT; return m_isCollectible; } |
425 | |
426 | DWORD GetNextModuleIndex() { LIMITED_METHOD_CONTRACT; return m_nextAvailableModuleIndex++; } |
427 | |
428 | void AddType(Module* pModule, |
429 | mdTypeDef cl); |
430 | void AddExportedType(mdExportedType cl); |
431 | mdAssemblyRef AddAssemblyRef(Assembly *refedAssembly, IMetaDataAssemblyEmit *pAssemEmitter = NULL, BOOL fUsePublicKeyToken = TRUE); |
432 | |
433 | //**************************************************************************************** |
434 | |
435 | DomainAssembly *GetDomainAssembly(AppDomain *pDomain); |
436 | void SetDomainAssembly(DomainAssembly *pAssembly); |
437 | |
438 | // Verison of GetDomainAssembly that uses the current AppDomain (N/A in DAC builds) |
439 | #ifndef DACCESS_COMPILE |
440 | DomainAssembly *GetDomainAssembly() { WRAPPER_NO_CONTRACT; return GetDomainAssembly(GetAppDomain()); } |
441 | #endif |
442 | |
443 | // FindDomainAssembly will return NULL if the assembly is not in the given domain |
444 | DomainAssembly *FindDomainAssembly(AppDomain *pDomain); |
445 | |
446 | #if defined(FEATURE_COLLECTIBLE_TYPES) && !defined(DACCESS_COMPILE) |
447 | OBJECTHANDLE GetLoaderAllocatorObjectHandle() { WRAPPER_NO_CONTRACT; return GetLoaderAllocator()->GetLoaderAllocatorObjectHandle(); } |
448 | #endif // FEATURE_COLLECTIBLE_TYPES |
449 | |
450 | BOOL IsSIMDVectorAssembly() { LIMITED_METHOD_DAC_CONTRACT; return m_fIsSIMDVectorAssembly; } |
451 | |
452 | #ifdef FEATURE_PREJIT |
453 | BOOL IsInstrumented(); |
454 | BOOL IsInstrumentedHelper(); |
455 | #endif // FEATURE_PREJIT |
456 | |
457 | #ifdef FEATURE_COMINTEROP |
458 | static ITypeLib * const InvalidTypeLib; |
459 | |
460 | // Get any cached ITypeLib* for the assembly. |
461 | ITypeLib *GetTypeLib(); |
462 | |
463 | // Try to set the ITypeLib*, if one is not already cached. |
464 | bool TrySetTypeLib(_In_ ITypeLib *pTlb); |
465 | #endif // FEATURE_COMINTEROP |
466 | |
467 | #ifndef DACCESS_COMPILE |
468 | |
469 | void DECLSPEC_NORETURN ThrowTypeLoadException(LPCUTF8 pszFullName, UINT resIDWhy); |
470 | |
471 | void DECLSPEC_NORETURN ThrowTypeLoadException(LPCUTF8 pszNameSpace, LPCUTF8 pTypeName, |
472 | UINT resIDWhy); |
473 | |
474 | void DECLSPEC_NORETURN ThrowTypeLoadException(NameHandle *pName, UINT resIDWhy); |
475 | |
476 | void DECLSPEC_NORETURN ThrowTypeLoadException(IMDInternalImport *pInternalImport, |
477 | mdToken token, |
478 | UINT resIDWhy); |
479 | |
480 | void DECLSPEC_NORETURN ThrowTypeLoadException(IMDInternalImport *pInternalImport, |
481 | mdToken token, |
482 | LPCUTF8 pszFieldOrMethodName, |
483 | UINT resIDWhy); |
484 | |
485 | void DECLSPEC_NORETURN ThrowTypeLoadException(LPCUTF8 pszNameSpace, |
486 | LPCUTF8 pszTypeName, |
487 | LPCUTF8 pszMethodName, |
488 | UINT resIDWhy); |
489 | |
490 | void DECLSPEC_NORETURN ThrowBadImageException(LPCUTF8 pszNameSpace, |
491 | LPCUTF8 pszTypeName, |
492 | UINT resIDWhy); |
493 | |
494 | #endif // #ifndef DACCESS_COMPILE |
495 | |
496 | //**************************************************************************************** |
497 | // |
498 | |
499 | static BOOL FileNotFound(HRESULT hr); |
500 | |
501 | //**************************************************************************************** |
502 | // Is the given assembly a friend of this assembly? |
503 | bool GrantsFriendAccessTo(Assembly *pAccessingAssembly, FieldDesc *pFD); |
504 | bool GrantsFriendAccessTo(Assembly *pAccessingAssembly, MethodDesc *pMD); |
505 | bool GrantsFriendAccessTo(Assembly *pAccessingAssembly, MethodTable *pMT); |
506 | bool IgnoresAccessChecksTo(Assembly *pAccessedAssembly); |
507 | |
508 | #ifdef FEATURE_COMINTEROP |
509 | bool IsImportedFromTypeLib() |
510 | { |
511 | WRAPPER_NO_CONTRACT; |
512 | return ((GetInteropAttributeMask() & INTEROP_ATTRIBUTE_IMPORTED_FROM_TYPELIB) != 0); |
513 | } |
514 | |
515 | bool IsPIAOrImportedFromTypeLib() |
516 | { |
517 | WRAPPER_NO_CONTRACT; |
518 | return ((GetInteropAttributeMask() & (INTEROP_ATTRIBUTE_IMPORTED_FROM_TYPELIB | INTEROP_ATTRIBUTE_PRIMARY_INTEROP_ASSEMBLY)) != 0); |
519 | } |
520 | |
521 | bool IsPIA() |
522 | { |
523 | WRAPPER_NO_CONTRACT; |
524 | return ((GetInteropAttributeMask() & INTEROP_ATTRIBUTE_PRIMARY_INTEROP_ASSEMBLY) != 0); |
525 | } |
526 | |
527 | // Does this assembly contain windows metadata |
528 | bool IsWinMD(); |
529 | |
530 | // Does this assembly contain windows metadata with managed implementation |
531 | bool IsManagedWinMD(); |
532 | |
533 | // Returns the IWinMDImport interface of the manifest module metadata or NULL if this assembly is not a .winmd |
534 | IWinMDImport *GetManifestWinMDImport(); |
535 | #endif |
536 | |
537 | |
538 | protected: |
539 | #ifdef FEATURE_COMINTEROP |
540 | enum WinMDStatus |
541 | { |
542 | WinMDStatus_Unknown, |
543 | WinMDStatus_IsPureWinMD, |
544 | WinMDStatus_IsManagedWinMD, |
545 | WinMDStatus_IsNotWinMD |
546 | }; |
547 | |
548 | // Determine if the assembly is a pure Windows Metadata file, contians managed implementation, or is not |
549 | // Windows Metadata at all. |
550 | WinMDStatus GetWinMDStatus(); |
551 | |
552 | enum InteropAttributeStatus { |
553 | INTEROP_ATTRIBUTE_UNSET = 0, |
554 | INTEROP_ATTRIBUTE_CACHED = 1, |
555 | INTEROP_ATTRIBUTE_IMPORTED_FROM_TYPELIB = 2, |
556 | INTEROP_ATTRIBUTE_PRIMARY_INTEROP_ASSEMBLY = 4, |
557 | }; |
558 | |
559 | InteropAttributeStatus GetInteropAttributeMask() |
560 | { |
561 | LIMITED_METHOD_CONTRACT; |
562 | |
563 | if (m_InteropAttributeStatus & INTEROP_ATTRIBUTE_CACHED) |
564 | return m_InteropAttributeStatus; |
565 | |
566 | int mask = INTEROP_ATTRIBUTE_UNSET; |
567 | |
568 | if (!IsWinMD()) // ignore classic COM interop CAs in .winmd |
569 | { |
570 | if (this->GetManifestImport()->GetCustomAttributeByName(TokenFromRid(1, mdtAssembly), INTEROP_IMPORTEDFROMTYPELIB_TYPE, 0, 0) == S_OK) |
571 | mask |= INTEROP_ATTRIBUTE_IMPORTED_FROM_TYPELIB; |
572 | if (this->GetManifestImport()->GetCustomAttributeByName(TokenFromRid(1, mdtAssembly), INTEROP_PRIMARYINTEROPASSEMBLY_TYPE, 0, 0) == S_OK) |
573 | mask |= INTEROP_ATTRIBUTE_PRIMARY_INTEROP_ASSEMBLY; |
574 | } |
575 | |
576 | if (!IsDynamic()) |
577 | { |
578 | mask |= INTEROP_ATTRIBUTE_CACHED; |
579 | m_InteropAttributeStatus = static_cast<InteropAttributeStatus>(mask); |
580 | } |
581 | |
582 | return static_cast<InteropAttributeStatus>(mask); |
583 | } |
584 | #endif // FEATURE_INTEROP |
585 | |
586 | private: |
587 | |
588 | //**************************************************************************************** |
589 | |
590 | void CacheManifestExportedTypes(AllocMemTracker *pamTracker); |
591 | void CacheManifestFiles(); |
592 | |
593 | void CacheFriendAssemblyInfo(); |
594 | |
595 | |
596 | PTR_BaseDomain m_pDomain; // Parent Domain |
597 | PTR_ClassLoader m_pClassLoader; // Single Loader |
598 | |
599 | |
600 | |
601 | PTR_MethodDesc m_pEntryPoint; // Method containing the entry point |
602 | PTR_Module m_pManifest; |
603 | PTR_PEAssembly m_pManifestFile; |
604 | |
605 | FriendAssemblyDescriptor *m_pFriendAssemblyDescriptor; |
606 | |
607 | BOOL m_isDynamic; |
608 | #ifdef FEATURE_COLLECTIBLE_TYPES |
609 | BOOL m_isCollectible; |
610 | #endif // FEATURE_COLLECTIBLE_TYPES |
611 | DWORD m_nextAvailableModuleIndex; |
612 | PTR_LoaderAllocator m_pLoaderAllocator; |
613 | DWORD m_isDisabledPrivateReflection; |
614 | |
615 | #ifdef FEATURE_COMINTEROP |
616 | // If a TypeLib is ever required for this module, cache the pointer here. |
617 | ITypeLib *m_pITypeLib; |
618 | InteropAttributeStatus m_InteropAttributeStatus; |
619 | |
620 | WinMDStatus m_winMDStatus; |
621 | IWinMDImport *m_pManifestWinMDImport; |
622 | #endif // FEATURE_COMINTEROP |
623 | |
624 | DebuggerAssemblyControlFlags m_debuggerFlags; |
625 | |
626 | BOOL m_fTerminated; |
627 | |
628 | BOOL m_fIsSIMDVectorAssembly; |
629 | |
630 | #ifdef FEATURE_PREJIT |
631 | enum IsInstrumentedStatus { |
632 | IS_INSTRUMENTED_UNSET = 0, |
633 | IS_INSTRUMENTED_FALSE = 1, |
634 | IS_INSTRUMENTED_TRUE = 2, |
635 | }; |
636 | IsInstrumentedStatus m_isInstrumentedStatus; |
637 | #endif // FEATURE_PREJIT |
638 | |
639 | }; |
640 | |
641 | typedef Assembly::ModuleIterator ModuleIterator; |
642 | |
643 | #ifndef DACCESS_COMPILE |
644 | |
645 | //--------------------------------------------------------------------------------------- |
646 | // |
647 | // FriendSecurityDescriptor contains information on which assemblies are friends of an assembly, as well as |
648 | // which individual internals are visible to those friend assemblies. |
649 | // |
650 | |
651 | class FriendAssemblyDescriptor |
652 | { |
653 | public: |
654 | ~FriendAssemblyDescriptor(); |
655 | |
656 | static |
657 | FriendAssemblyDescriptor *CreateFriendAssemblyDescriptor(PEAssembly *pAssembly); |
658 | |
659 | //--------------------------------------------------------------------------------------- |
660 | // |
661 | // Checks to see if an assembly has friend access to a particular member. |
662 | // |
663 | // Arguments: |
664 | // pAccessingAssembly - the assembly requesting friend access |
665 | // pMember - the member that is attempting to be accessed |
666 | // |
667 | // Return Value: |
668 | // true if friend access is allowed, false otherwise |
669 | // |
670 | // Notes: |
671 | // Template type T should be either FieldDesc, MethodDesc, or MethodTable. |
672 | // |
673 | |
674 | template <class T> |
675 | bool GrantsFriendAccessTo(Assembly *pAccessingAssembly, T *pMember) |
676 | { |
677 | CONTRACTL |
678 | { |
679 | THROWS; |
680 | GC_TRIGGERS; |
681 | PRECONDITION(CheckPointer(pAccessingAssembly)); |
682 | PRECONDITION(CheckPointer(pMember)); |
683 | } |
684 | CONTRACTL_END; |
685 | |
686 | return IsAssemblyOnList(pAccessingAssembly, m_alFullAccessFriendAssemblies); |
687 | } |
688 | |
689 | |
690 | bool IgnoresAccessChecksTo(Assembly *pAccessedAssembly) |
691 | { |
692 | return IsAssemblyOnList(pAccessedAssembly, m_subjectAssemblies); |
693 | } |
694 | |
695 | private: |
696 | typedef AssemblySpec FriendAssemblyName_t; |
697 | typedef NewHolder<AssemblySpec> FriendAssemblyNameHolder; |
698 | |
699 | ArrayList m_alFullAccessFriendAssemblies; // Friend assemblies which have access to all internals |
700 | ArrayList m_subjectAssemblies; // Subject assemblies which we will not perform access checks against |
701 | |
702 | FriendAssemblyDescriptor(); |
703 | |
704 | void AddFriendAssembly(FriendAssemblyName_t *pFriendAssembly); |
705 | void AddSubjectAssembly(FriendAssemblyName_t *pSubjectAssembly); |
706 | |
707 | static |
708 | bool IsAssemblyOnList(Assembly *pAssembly, const ArrayList &alAssemblyNames) |
709 | { |
710 | return IsAssemblyOnList(pAssembly->GetManifestFile(), alAssemblyNames); |
711 | } |
712 | |
713 | static |
714 | bool IsAssemblyOnList(PEAssembly *pAssembly, const ArrayList &alAssemblyNames); |
715 | }; |
716 | |
717 | #endif // !DACCESS_COMPILE |
718 | |
719 | |
720 | #endif |
721 | |