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// AssemblyName.cpp
7//
8
9
10//
11// Implements the AssemblyName class
12//
13// ============================================================
14
15#define DISABLE_BINDER_DEBUG_LOGGING
16
17#include "assemblyname.hpp"
18#include "assembly.hpp"
19#include "utils.hpp"
20#include "variables.hpp"
21
22#include "fusionassemblyname.hpp"
23
24#include "textualidentityparser.hpp"
25
26#include "corpriv.h"
27
28#include "ex.h"
29
30namespace BINDER_SPACE
31{
32 AssemblyName::AssemblyName()
33 {
34 m_cRef = 1;
35 m_dwNameFlags = NAME_FLAG_NONE;
36 // Default values present in every assembly name
37 SetHave(AssemblyIdentity::IDENTITY_FLAG_CULTURE |
38 AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY_TOKEN_NULL);
39 }
40
41 AssemblyName::~AssemblyName()
42 {
43 // Nothing to do here
44 }
45
46 HRESULT AssemblyName::Init(IMDInternalImport *pIMetaDataAssemblyImport,
47 PEKIND PeKind,
48 mdAssemblyRef mdar /* = 0 */,
49 BOOL fIsDefinition /* = TRUE */)
50 {
51 HRESULT hr = S_OK;
52 mdAssembly mda = 0;
53 AssemblyMetaDataInternal amd = {0};
54 CONST VOID *pvPublicKeyToken = NULL;
55 DWORD dwPublicKeyToken = 0;
56 LPCSTR pAssemblyName = NULL;
57 DWORD dwRefOrDefFlags = 0;
58 DWORD dwHashAlgId = 0;
59
60 BINDER_LOG_ENTER(L"AssemblyName::Init(IMetaDataAssemblyImport)");
61
62 if (fIsDefinition)
63 {
64 // Get the assembly token
65 IF_FAIL_GO(pIMetaDataAssemblyImport->GetAssemblyFromScope(&mda));
66 }
67
68 BINDER_LOG(L"Have mda scope!");
69
70 // Get name and metadata
71 if (fIsDefinition)
72 {
73 IF_FAIL_GO(pIMetaDataAssemblyImport->GetAssemblyProps(
74 mda, // [IN] The Assembly for which to get the properties.
75 &pvPublicKeyToken, // [OUT] Pointer to the PublicKeyToken blob.
76 &dwPublicKeyToken, // [OUT] Count of bytes in the PublicKeyToken Blob.
77 &dwHashAlgId, // [OUT] Hash Algorithm.
78 &pAssemblyName, // [OUT] Name.
79 &amd, // [OUT] Assembly MetaData.
80 &dwRefOrDefFlags // [OUT] Flags.
81 ));
82 }
83 else
84 {
85 IF_FAIL_GO(pIMetaDataAssemblyImport->GetAssemblyRefProps(
86 mdar, // [IN] The Assembly for which to get the properties.
87 &pvPublicKeyToken, // [OUT] Pointer to the PublicKeyToken blob.
88 &dwPublicKeyToken, // [OUT] Count of bytes in the PublicKeyToken Blob.
89 &pAssemblyName, // [OUT] Name.
90 &amd, // [OUT] Assembly MetaData.
91 NULL, // [OUT] Hash blob.
92 NULL, // [OUT] Count of bytes in hash blob.
93 &dwRefOrDefFlags // [OUT] Flags.
94 ));
95 }
96
97 BINDER_LOG(L"Have props!");
98
99 {
100 StackSString culture;
101 culture.SetUTF8(amd.szLocale);
102 culture.Normalize();
103
104 SString::CIterator itr = culture.Begin();
105 if (culture.Find(itr, L';'))
106 {
107 culture = SString(culture, culture.Begin(), itr-1);
108 }
109
110 SetCulture(culture);
111 }
112
113 {
114 StackSString assemblyName;
115 assemblyName.SetUTF8(pAssemblyName);
116 assemblyName.Normalize();
117
118 COUNT_T assemblyNameLength = assemblyName.GetCount();
119 if (assemblyNameLength == 0 || assemblyNameLength >= MAX_PATH_FNAME)
120 {
121 IF_FAIL_GO(FUSION_E_INVALID_NAME);
122 }
123
124 SetSimpleName(assemblyName);
125 }
126
127 // See if the assembly[def] is retargetable (ie, for a generic assembly).
128 if (IsAfRetargetable(dwRefOrDefFlags))
129 {
130 SetIsRetargetable(TRUE);
131 }
132
133 // Set ContentType
134 if (IsAfContentType_Default(dwRefOrDefFlags))
135 {
136 SetContentType(AssemblyContentType_Default);
137 }
138 else if (IsAfContentType_WindowsRuntime(dwRefOrDefFlags))
139 {
140 SetContentType(AssemblyContentType_WindowsRuntime);
141 }
142 else
143 {
144 IF_FAIL_GO(FUSION_E_INVALID_NAME);
145 }
146
147 // Set the assembly version
148 {
149 AssemblyVersion *pAssemblyVersion = GetVersion();
150
151 pAssemblyVersion->SetFeatureVersion(amd.usMajorVersion, amd.usMinorVersion);
152 pAssemblyVersion->SetServiceVersion(amd.usBuildNumber, amd.usRevisionNumber);
153 SetHave(AssemblyIdentity::IDENTITY_FLAG_VERSION);
154 }
155
156 // Set public key and/or public key token (if we have it)
157 if (pvPublicKeyToken && dwPublicKeyToken)
158 {
159 SBuffer publicKeyOrTokenBLOB((const BYTE *) pvPublicKeyToken, dwPublicKeyToken);
160
161 if (IsAfPublicKey(dwRefOrDefFlags))
162 {
163 SBuffer publicKeyTokenBLOB;
164
165 IF_FAIL_GO(GetTokenFromPublicKey(publicKeyOrTokenBLOB, publicKeyTokenBLOB));
166 GetPublicKeyTokenBLOB().Set(publicKeyTokenBLOB);
167 }
168 else
169 {
170 GetPublicKeyTokenBLOB().Set(publicKeyOrTokenBLOB);
171 }
172
173 SetHave(AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY_TOKEN);
174 }
175
176 SetArchitecture(PeKind);
177
178 Exit:
179 BINDER_LOG_LEAVE_HR(L"AssemblyName::Init(IMetaDataAssemblyImport)", hr);
180 return hr;
181 }
182
183 HRESULT AssemblyName::Init(SString &assemblyDisplayName)
184 {
185 HRESULT hr = S_OK;
186 BINDER_LOG_ENTER(L"AssemblyName::Init(assemblyDisplayName)");
187
188 BINDER_LOG_STRING(L"assemblyDisplayName", assemblyDisplayName);
189
190 IF_FAIL_GO(TextualIdentityParser::Parse(assemblyDisplayName, this));
191
192 Exit:
193 BINDER_LOG_LEAVE_HR(L"AssemblyName::Init(assemblyDisplayName)", hr);
194 return hr;
195 }
196
197 HRESULT AssemblyName::Init(IAssemblyName *pIAssemblyName)
198 {
199 HRESULT hr = S_OK;
200
201 _ASSERTE(pIAssemblyName != NULL);
202
203 EX_TRY
204 {
205 {
206 // Set the simpleName
207 StackSString simpleName;
208 hr = fusion::util::GetSimpleName(pIAssemblyName, simpleName);
209 IF_FAIL_GO(hr);
210 SetSimpleName(simpleName);
211 SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_SIMPLE_NAME);
212 }
213
214 // Display version
215 DWORD dwVersionParts[4] = {0,0,0,0};
216 DWORD cbVersionSize = sizeof(dwVersionParts[0]);
217 hr = fusion::util::GetProperty(pIAssemblyName, ASM_NAME_MAJOR_VERSION, static_cast<PVOID>(&dwVersionParts[0]), &cbVersionSize);
218 IF_FAIL_GO(hr);
219 if ((hr == S_OK) && (cbVersionSize != 0))
220 {
221 // Property is present - loop to get the individual version details
222 for(DWORD i = 0; i < 4; i++)
223 {
224 cbVersionSize = sizeof(dwVersionParts[i]);
225 hr = fusion::util::GetProperty(pIAssemblyName, ASM_NAME_MAJOR_VERSION+i, static_cast<PVOID>(&dwVersionParts[i]), &cbVersionSize);
226 IF_FAIL_GO(hr);
227 }
228
229 m_version.SetFeatureVersion(dwVersionParts[0], dwVersionParts[1]);
230 m_version.SetServiceVersion(dwVersionParts[2], dwVersionParts[3]);
231 SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_VERSION);
232 }
233
234 {
235 // Display culture
236 StackSString culture;
237 hr = fusion::util::GetProperty(pIAssemblyName, ASM_NAME_CULTURE, culture);
238 IF_FAIL_GO(hr);
239 if (hr == S_OK)
240 {
241 SetCulture(culture);
242 SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_CULTURE);
243 }
244 }
245
246 {
247 // Display public key token
248 NewArrayHolder<BYTE> pPublicKeyToken;
249 DWORD cbPublicKeyToken = 0;
250 hr = fusion::util::GetProperty(pIAssemblyName, ASM_NAME_PUBLIC_KEY_TOKEN, static_cast<PBYTE*>(&pPublicKeyToken), &cbPublicKeyToken);
251 IF_FAIL_GO(hr);
252 if ((hr == S_OK) && (cbPublicKeyToken != 0))
253 {
254 m_publicKeyOrTokenBLOB.Set(pPublicKeyToken, cbPublicKeyToken);
255 SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY_TOKEN);
256 }
257 else
258 {
259 SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY_TOKEN_NULL);
260 }
261 }
262
263 // Display processor architecture
264 DWORD peKind = 0;
265 DWORD cbPeKind = sizeof(peKind);
266 hr = fusion::util::GetProperty(pIAssemblyName, ASM_NAME_ARCHITECTURE, static_cast<PVOID>(&peKind), &cbPeKind);
267 IF_FAIL_GO(hr);
268 if ((hr == S_OK) && (cbPeKind != 0))
269 {
270 PEKIND PeKind = (PEKIND)peKind;
271 if (PeKind != peNone)
272 {
273 SetArchitecture(PeKind);
274 SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_PROCESSOR_ARCHITECTURE);
275 }
276 }
277
278 // Display retarget flag
279 BOOL fRetarget = FALSE;
280 DWORD cbRetarget = sizeof(fRetarget);
281 hr = fusion::util::GetProperty(pIAssemblyName, ASM_NAME_RETARGET, static_cast<PVOID>(&fRetarget), &cbRetarget);
282 IF_FAIL_GO(hr);
283 if ((hr == S_OK) && (cbRetarget != 0))
284 {
285 if (fRetarget)
286 {
287 SetIsRetargetable(fRetarget);
288 SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_RETARGETABLE);
289 }
290 }
291
292 // Display content type
293 DWORD dwContentType = AssemblyContentType_Default;
294 DWORD cbContentType = sizeof(dwContentType);
295 hr = fusion::util::GetProperty(pIAssemblyName, ASM_NAME_CONTENT_TYPE, static_cast<PVOID>(&dwContentType), &cbContentType);
296 IF_FAIL_GO(hr);
297 if ((hr == S_OK) && (cbContentType != 0))
298 {
299 if (dwContentType != AssemblyContentType_Default)
300 {
301 SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_CONTENT_TYPE);
302 SetContentType((AssemblyContentType)dwContentType);
303 }
304 }
305
306 {
307 // Display custom flag. Dont set it if it is not present since that will end up adding the "Custom=null" attribute
308 // in the displayname of the assembly that maybe generated using this AssemblyName instance. This could create conflict when
309 // the displayname is generated from the assembly directly as that will not have a "Custom" field set.
310 NewArrayHolder<BYTE> pCustomBLOB;
311 DWORD cbCustomBLOB = 0;
312 hr = fusion::util::GetProperty(pIAssemblyName, ASM_NAME_CUSTOM, static_cast<PBYTE*>(&pCustomBLOB), &cbCustomBLOB);
313 IF_FAIL_GO(hr);
314 if ((hr == S_OK) && (cbCustomBLOB != 0))
315 {
316 m_customBLOB.Set(pCustomBLOB, cbCustomBLOB);
317 SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_CUSTOM);
318 }
319 }
320 }
321 EX_CATCH_HRESULT(hr);
322Exit:
323 return hr;
324 }
325
326 HRESULT AssemblyName::CreateFusionName(IAssemblyName **ppIAssemblyName)
327 {
328 HRESULT hr = S_OK;
329 ReleaseHolder<IAssemblyName> pIAssemblyName;
330
331 IF_FAIL_GO(CreateAssemblyNameObject(&pIAssemblyName, NULL, 0, NULL));
332
333 IF_FAIL_GO(LegacyFusion::SetStringProperty(pIAssemblyName, ASM_NAME_NAME, GetSimpleName()));
334
335 if (Have(AssemblyIdentity::IDENTITY_FLAG_VERSION))
336 {
337 AssemblyVersion *pAssemblyVersion = GetVersion();
338
339 IF_FAIL_GO(LegacyFusion::SetWordProperty(pIAssemblyName,
340 ASM_NAME_MAJOR_VERSION,
341 pAssemblyVersion->GetMajor()));
342 IF_FAIL_GO(LegacyFusion::SetWordProperty(pIAssemblyName,
343 ASM_NAME_MINOR_VERSION,
344 pAssemblyVersion->GetMinor()));
345 IF_FAIL_GO(LegacyFusion::SetWordProperty(pIAssemblyName,
346 ASM_NAME_BUILD_NUMBER,
347 pAssemblyVersion->GetBuild()));
348 IF_FAIL_GO(LegacyFusion::SetWordProperty(pIAssemblyName,
349 ASM_NAME_REVISION_NUMBER,
350 pAssemblyVersion->GetRevision()));
351 }
352
353 if (Have(AssemblyIdentity::IDENTITY_FLAG_CULTURE))
354 {
355 IF_FAIL_GO(LegacyFusion::SetStringProperty(pIAssemblyName, ASM_NAME_CULTURE, GetCulture()));
356 }
357
358 if (Have(AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY))
359 {
360 // GetPublicKeyTokenBLOB contains either PK or PKT.
361 IF_FAIL_GO(LegacyFusion::SetBufferProperty(pIAssemblyName,
362 ASM_NAME_PUBLIC_KEY,
363 GetPublicKeyTokenBLOB()));
364 }
365 else if (Have(AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY_TOKEN))
366 {
367 // GetPublicKeyTokenBLOB contains either PK or PKT.
368 IF_FAIL_GO(LegacyFusion::SetBufferProperty(pIAssemblyName,
369 ASM_NAME_PUBLIC_KEY_TOKEN,
370 GetPublicKeyTokenBLOB()));
371 }
372
373 if (Have(AssemblyIdentity::IDENTITY_FLAG_PROCESSOR_ARCHITECTURE))
374 {
375 IF_FAIL_GO(LegacyFusion::SetDwordProperty(pIAssemblyName,
376 ASM_NAME_ARCHITECTURE,
377 static_cast<DWORD>(GetArchitecture())));
378 }
379
380 if (Have(AssemblyIdentity::IDENTITY_FLAG_CONTENT_TYPE))
381 {
382 IF_FAIL_GO(LegacyFusion::SetDwordProperty(pIAssemblyName,
383 ASM_NAME_CONTENT_TYPE,
384 GetContentType()));
385 }
386
387 *ppIAssemblyName = pIAssemblyName.Extract();
388
389 Exit:
390 return hr;
391 }
392
393 ULONG AssemblyName::AddRef()
394 {
395 return InterlockedIncrement(&m_cRef);
396 }
397
398 ULONG AssemblyName::Release()
399 {
400 ULONG ulRef = InterlockedDecrement(&m_cRef);
401 if (ulRef == 0)
402 {
403 delete this;
404 }
405 return ulRef;
406 }
407
408 SString &AssemblyName::GetDeNormalizedCulture()
409 {
410 SString &culture = GetCulture();
411
412 if (EqualsCaseInsensitive(culture, g_BinderVariables->cultureNeutral))
413 {
414 culture = g_BinderVariables->emptyString;
415 }
416
417 return culture;
418 }
419
420 BOOL AssemblyName::IsStronglyNamed()
421 {
422 return Have(AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY_TOKEN);
423 }
424
425 BOOL AssemblyName::IsMscorlib()
426 {
427 // TODO: Is this simple comparison enough?
428 return EqualsCaseInsensitive(GetSimpleName(), g_BinderVariables->mscorlib);
429 }
430
431 HRESULT AssemblyName::SetArchitecture(SString &architecture)
432 {
433 HRESULT hr = S_OK;
434
435 if (architecture.IsEmpty())
436 {
437 SetArchitecture(peNone);
438 }
439 else if (EqualsCaseInsensitive(architecture, g_BinderVariables->architectureMSIL))
440 {
441 SetArchitecture(peMSIL);
442 }
443 else if (EqualsCaseInsensitive(architecture, g_BinderVariables->architectureX86))
444 {
445 SetArchitecture(peI386);
446 }
447 else if (EqualsCaseInsensitive(architecture, g_BinderVariables->architectureAMD64))
448 {
449 SetArchitecture(peAMD64);
450 }
451 else if (EqualsCaseInsensitive(architecture, g_BinderVariables->architectureARM))
452 {
453 SetArchitecture(peARM);
454 }
455 else if (EqualsCaseInsensitive(architecture, g_BinderVariables->architectureARM64))
456 {
457 SetArchitecture(peARM64);
458 }
459 else
460 {
461 hr = FUSION_E_MANIFEST_PARSE_ERROR;
462 }
463
464 return hr;
465 }
466
467 ULONG AssemblyName::Hash(DWORD dwIncludeFlags)
468 {
469 DWORD dwHash = 0;
470 DWORD dwUseIdentityFlags = m_dwIdentityFlags;
471
472 // Prune unwanted name parts
473 if ((dwIncludeFlags & INCLUDE_VERSION) == 0)
474 {
475 dwUseIdentityFlags &= ~AssemblyIdentity::IDENTITY_FLAG_VERSION;
476 }
477 if ((dwIncludeFlags & INCLUDE_ARCHITECTURE) == 0)
478 {
479 dwUseIdentityFlags &= ~AssemblyIdentity::IDENTITY_FLAG_PROCESSOR_ARCHITECTURE;
480 }
481 if ((dwIncludeFlags & INCLUDE_RETARGETABLE) == 0)
482 {
483 dwUseIdentityFlags &= ~AssemblyIdentity::IDENTITY_FLAG_RETARGETABLE;
484 }
485 if ((dwIncludeFlags & INCLUDE_CONTENT_TYPE) == 0)
486 {
487 dwUseIdentityFlags &= ~AssemblyIdentity::IDENTITY_FLAG_CONTENT_TYPE;
488 }
489
490 dwHash ^= static_cast<DWORD>(HashCaseInsensitive(GetSimpleName()));
491 dwHash = _rotl(dwHash, 4);
492
493 if (AssemblyIdentity::Have(dwUseIdentityFlags,
494 AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY) ||
495 AssemblyIdentity::Have(dwUseIdentityFlags,
496 AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY_TOKEN))
497 {
498 const BYTE *pbPublicKeyOrToken = GetPublicKeyTokenBLOB();
499 DWORD dwcbPublicKeyOrToken = GetPublicKeyTokenBLOB().GetSize();
500
501 _ASSERTE(pbPublicKeyOrToken != NULL);
502
503 dwHash ^= HashBytes(pbPublicKeyOrToken, dwcbPublicKeyOrToken);
504 dwHash = _rotl(dwHash, 4);
505 }
506
507 if (AssemblyIdentity::Have(dwUseIdentityFlags, AssemblyIdentity::IDENTITY_FLAG_VERSION))
508 {
509 AssemblyVersion *pAssemblyVersion = GetVersion();
510
511 dwHash ^= pAssemblyVersion->GetMajor();
512 dwHash = _rotl(dwHash, 8);
513 dwHash ^= pAssemblyVersion->GetMinor();
514 dwHash = _rotl(dwHash, 8);
515 dwHash ^= pAssemblyVersion->GetBuild();
516 dwHash = _rotl(dwHash, 8);
517 dwHash ^= pAssemblyVersion->GetRevision();
518 dwHash = _rotl(dwHash, 8);
519 }
520
521 if (AssemblyIdentity::Have(dwUseIdentityFlags, AssemblyIdentity::IDENTITY_FLAG_CULTURE))
522 {
523 dwHash ^= static_cast<DWORD>(HashCaseInsensitive(GetNormalizedCulture()));
524 dwHash = _rotl(dwHash, 4);
525 }
526
527 if (AssemblyIdentity::Have(dwUseIdentityFlags,
528 AssemblyIdentity::IDENTITY_FLAG_RETARGETABLE))
529 {
530 dwHash ^= 1;
531 dwHash = _rotl(dwHash, 4);
532 }
533
534 if (AssemblyIdentity::Have(dwUseIdentityFlags,
535 AssemblyIdentity::IDENTITY_FLAG_PROCESSOR_ARCHITECTURE))
536 {
537 dwHash ^= static_cast<DWORD>(GetArchitecture());
538 dwHash = _rotl(dwHash, 4);
539 }
540
541 if (AssemblyIdentity::Have(dwUseIdentityFlags,
542 AssemblyIdentity::IDENTITY_FLAG_CONTENT_TYPE))
543 {
544 dwHash ^= static_cast<DWORD>(GetContentType());
545 dwHash = _rotl(dwHash, 4);
546 }
547
548 return static_cast<ULONG>(dwHash);
549 }
550
551 BOOL AssemblyName::Equals(AssemblyName *pAssemblyName,
552 DWORD dwIncludeFlags)
553 {
554 BOOL fEquals = FALSE;
555
556 if (GetContentType() == AssemblyContentType_WindowsRuntime)
557 { // Assembly is meaningless for WinRT, all assemblies form one joint type namespace
558 return (GetContentType() == pAssemblyName->GetContentType());
559 }
560
561 if (EqualsCaseInsensitive(GetSimpleName(), pAssemblyName->GetSimpleName()) &&
562 (GetContentType() == pAssemblyName->GetContentType()))
563 {
564 fEquals = TRUE;
565
566 if ((dwIncludeFlags & EXCLUDE_CULTURE) == 0)
567 {
568 fEquals = EqualsCaseInsensitive(GetNormalizedCulture(), pAssemblyName->GetNormalizedCulture());
569 }
570
571 if (fEquals && (dwIncludeFlags & INCLUDE_PUBLIC_KEY_TOKEN) != 0)
572 {
573 fEquals = (GetPublicKeyTokenBLOB().Equals(pAssemblyName->GetPublicKeyTokenBLOB()));
574 }
575
576 if (fEquals && ((dwIncludeFlags & INCLUDE_ARCHITECTURE) != 0))
577 {
578 fEquals = (GetArchitecture() == pAssemblyName->GetArchitecture());
579 }
580
581 if (fEquals && ((dwIncludeFlags & INCLUDE_VERSION) != 0))
582 {
583 fEquals = GetVersion()->Equals(pAssemblyName->GetVersion());
584 }
585
586 if (fEquals && ((dwIncludeFlags & INCLUDE_RETARGETABLE) != 0))
587 {
588 fEquals = (GetIsRetargetable() == pAssemblyName->GetIsRetargetable());
589 }
590 }
591
592 return fEquals;
593 }
594
595 BOOL AssemblyName::RefEqualsDef(AssemblyName *pAssemblyNameDef,
596 BOOL fInspectionOnly)
597 {
598 BOOL fEquals = FALSE;
599
600 if (GetContentType() == AssemblyContentType_WindowsRuntime)
601 { // Assembly is meaningless for WinRT, all assemblies form one joint type namespace
602 return (GetContentType() == pAssemblyNameDef->GetContentType());
603 }
604
605 if (EqualsCaseInsensitive(GetSimpleName(), pAssemblyNameDef->GetSimpleName()) &&
606 EqualsCaseInsensitive(GetNormalizedCulture(),
607 pAssemblyNameDef->GetNormalizedCulture()) &&
608 GetPublicKeyTokenBLOB().Equals(pAssemblyNameDef->GetPublicKeyTokenBLOB()) &&
609 (GetContentType() == pAssemblyNameDef->GetContentType()))
610 {
611 PEKIND kRefArchitecture = GetArchitecture();
612 PEKIND kDefArchitecture = pAssemblyNameDef->GetArchitecture();
613
614 if (kRefArchitecture == peNone)
615 {
616 fEquals = (fInspectionOnly ||
617 (kDefArchitecture == peNone) ||
618 (kDefArchitecture == peMSIL) ||
619 (kDefArchitecture == Assembly::GetSystemArchitecture()));
620 }
621 else
622 {
623 fEquals = (kRefArchitecture == kDefArchitecture);
624 }
625 }
626
627 return fEquals;
628 }
629
630 HRESULT AssemblyName::Clone(AssemblyName **ppAssemblyName)
631 {
632 HRESULT hr = S_OK;
633 AssemblyName *pClonedAssemblyName = NULL;
634
635 SAFE_NEW(pClonedAssemblyName, AssemblyName);
636 CloneInto(pClonedAssemblyName);
637 pClonedAssemblyName->m_dwNameFlags = m_dwNameFlags;
638
639 *ppAssemblyName = pClonedAssemblyName;
640
641 Exit:
642 return hr;
643 }
644
645 void AssemblyName::GetDisplayName(PathString &displayName,
646 DWORD dwIncludeFlags)
647 {
648 DWORD dwUseIdentityFlags = m_dwIdentityFlags;
649
650 // Prune unwanted name parts
651 if ((dwIncludeFlags & INCLUDE_VERSION) == 0)
652 {
653 dwUseIdentityFlags &= ~AssemblyIdentity::IDENTITY_FLAG_VERSION;
654 }
655 if ((dwIncludeFlags & INCLUDE_ARCHITECTURE) == 0)
656 {
657 dwUseIdentityFlags &= ~AssemblyIdentity::IDENTITY_FLAG_PROCESSOR_ARCHITECTURE;
658 }
659 if ((dwIncludeFlags & INCLUDE_RETARGETABLE) == 0)
660 {
661 dwUseIdentityFlags &= ~AssemblyIdentity::IDENTITY_FLAG_RETARGETABLE;
662 }
663 if ((dwIncludeFlags & INCLUDE_CONTENT_TYPE) == 0)
664 {
665 dwUseIdentityFlags &= ~AssemblyIdentity::IDENTITY_FLAG_CONTENT_TYPE;
666 }
667
668 TextualIdentityParser::ToString(this, dwUseIdentityFlags, displayName);
669 }
670
671 SString &AssemblyName::ArchitectureToString(PEKIND kArchitecture)
672 {
673 switch (kArchitecture)
674 {
675 case peNone:
676 return g_BinderVariables->emptyString;
677 case peMSIL:
678 return g_BinderVariables->architectureMSIL;
679 case peI386:
680 return g_BinderVariables->architectureX86;
681 case peAMD64:
682 return g_BinderVariables->architectureAMD64;
683 case peARM:
684 return g_BinderVariables->architectureARM;
685 case peARM64:
686 return g_BinderVariables->architectureARM64;
687 default:
688 _ASSERTE(0);
689 return g_BinderVariables->emptyString;
690 }
691 }
692
693 SString &AssemblyName::GetNormalizedCulture()
694 {
695 SString &culture = GetCulture();
696
697 if (culture.IsEmpty())
698 {
699 culture = g_BinderVariables->cultureNeutral;
700 }
701
702 return culture;
703 }
704}; // namespace BINDER_SPACE
705