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 | |
30 | namespace 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); |
322 | Exit: |
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 | |