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 | // CoreAssemblySpec.cpp |
7 | // |
8 | |
9 | |
10 | // |
11 | // CoreCLR specific implementation of AssemblySpec and BaseAssemblySpec |
12 | // ============================================================ |
13 | |
14 | #include "common.h" |
15 | #include "peimage.h" |
16 | #include "appdomain.inl" |
17 | #include <peimage.h> |
18 | #include "peimagelayout.inl" |
19 | #include "domainfile.h" |
20 | #include "holder.h" |
21 | #include "../binder/inc/assemblybinder.hpp" |
22 | |
23 | #ifdef FEATURE_PREJIT |
24 | #include "compile.h" |
25 | #endif |
26 | |
27 | |
28 | #include "../binder/inc/textualidentityparser.hpp" |
29 | #include "../binder/inc/assemblyidentity.hpp" |
30 | #include "../binder/inc/assembly.hpp" |
31 | #include "../binder/inc/assemblyname.hpp" |
32 | #include "../binder/inc/fusionassemblyname.hpp" |
33 | |
34 | #include "../binder/inc/coreclrbindercommon.h" |
35 | #include "../binder/inc/applicationcontext.hpp" |
36 | #ifndef DACCESS_COMPILE |
37 | |
38 | STDAPI BinderGetImagePath(PEImage *pPEImage, |
39 | SString &imagePath) |
40 | { |
41 | HRESULT hr = S_OK; |
42 | |
43 | _ASSERTE(pPEImage != NULL); |
44 | |
45 | imagePath.Set(pPEImage->GetPath()); |
46 | return hr; |
47 | } |
48 | |
49 | STDAPI BinderAddRefPEImage(PEImage *pPEImage) |
50 | { |
51 | HRESULT hr = S_OK; |
52 | |
53 | if (pPEImage != NULL) |
54 | { |
55 | pPEImage->AddRef(); |
56 | } |
57 | |
58 | return hr; |
59 | } |
60 | |
61 | STDAPI BinderReleasePEImage(PEImage *pPEImage) |
62 | { |
63 | HRESULT hr = S_OK; |
64 | |
65 | if (pPEImage != NULL) |
66 | { |
67 | pPEImage->Release(); |
68 | } |
69 | |
70 | return hr; |
71 | } |
72 | |
73 | STDAPI BinderGetDisplayName(PEAssembly *pAssembly, |
74 | SString &displayName) |
75 | { |
76 | HRESULT hr = S_OK; |
77 | |
78 | if (pAssembly != NULL) |
79 | { |
80 | pAssembly->GetDisplayName(displayName, ASM_DISPLAYF_FULL); |
81 | } |
82 | |
83 | return hr; |
84 | } |
85 | |
86 | |
87 | |
88 | static VOID ThrowLoadError(AssemblySpec * pSpec, HRESULT hr) |
89 | { |
90 | CONTRACTL |
91 | { |
92 | THROWS; |
93 | MODE_ANY; |
94 | GC_TRIGGERS; |
95 | } |
96 | CONTRACTL_END; |
97 | |
98 | StackSString name; |
99 | pSpec->GetFileOrDisplayName(0, name); |
100 | EEFileLoadException::Throw(name, hr); |
101 | } |
102 | |
103 | // See code:BINDER_SPACE::AssemblyBinder::GetAssembly for info on fNgenExplicitBind |
104 | // and fExplicitBindToNativeImage, and see code:CEECompileInfo::LoadAssemblyByPath |
105 | // for an example of how they're used. |
106 | VOID AssemblySpec::Bind(AppDomain *pAppDomain, |
107 | BOOL fThrowOnFileNotFound, |
108 | CoreBindResult *pResult, |
109 | BOOL fNgenExplicitBind /* = FALSE */, |
110 | BOOL fExplicitBindToNativeImage /* = FALSE */) |
111 | { |
112 | CONTRACTL |
113 | { |
114 | INSTANCE_CHECK; |
115 | STANDARD_VM_CHECK; |
116 | PRECONDITION(CheckPointer(pResult)); |
117 | PRECONDITION(CheckPointer(pAppDomain)); |
118 | PRECONDITION(IsMscorlib() == FALSE); // This should never be called for MSCORLIB (explicit loading) |
119 | } |
120 | CONTRACTL_END; |
121 | |
122 | ReleaseHolder<BINDER_SPACE::Assembly> result; |
123 | HRESULT hr=S_OK; |
124 | |
125 | SString assemblyDisplayName; |
126 | |
127 | pResult->Reset(); |
128 | |
129 | if (m_wszCodeBase==NULL) |
130 | { |
131 | GetFileOrDisplayName(0, assemblyDisplayName); |
132 | } |
133 | |
134 | // Have a default binding context setup |
135 | ICLRPrivBinder *pBinder = GetBindingContextFromParentAssembly(pAppDomain); |
136 | |
137 | // Get the reference to the TPABinder context |
138 | CLRPrivBinderCoreCLR *pTPABinder = pAppDomain->GetTPABinderContext(); |
139 | |
140 | ReleaseHolder<ICLRPrivAssembly> pPrivAsm; |
141 | _ASSERTE(pBinder != NULL); |
142 | |
143 | if (m_wszCodeBase==NULL && IsMscorlibSatellite()) |
144 | { |
145 | StackSString sSystemDirectory(SystemDomain::System()->SystemDirectory()); |
146 | StackSString tmpString; |
147 | StackSString sSimpleName; |
148 | StackSString sCultureName; |
149 | |
150 | tmpString.SetUTF8(m_pAssemblyName); |
151 | tmpString.ConvertToUnicode(sSimpleName); |
152 | |
153 | tmpString.Clear(); |
154 | if ((m_context.szLocale != NULL) && (m_context.szLocale[0] != 0)) |
155 | { |
156 | tmpString.SetUTF8(m_context.szLocale); |
157 | tmpString.ConvertToUnicode(sCultureName); |
158 | } |
159 | |
160 | hr = CCoreCLRBinderHelper::BindToSystemSatellite(sSystemDirectory, sSimpleName, sCultureName, &pPrivAsm); |
161 | } |
162 | else if(m_wszCodeBase==NULL) |
163 | { |
164 | // For name based binding these arguments shouldnt have been changed from default |
165 | _ASSERTE(!fNgenExplicitBind && !fExplicitBindToNativeImage); |
166 | SafeComHolder<IAssemblyName> pName; |
167 | hr = CreateAssemblyNameObject(&pName, assemblyDisplayName, CANOF_PARSE_DISPLAY_NAME, NULL); |
168 | if (SUCCEEDED(hr)) |
169 | { |
170 | hr = pBinder->BindAssemblyByName(pName, &pPrivAsm); |
171 | } |
172 | } |
173 | else |
174 | { |
175 | hr = pTPABinder->Bind(assemblyDisplayName, |
176 | m_wszCodeBase, |
177 | GetParentAssembly()? GetParentAssembly()->GetFile():NULL, |
178 | fNgenExplicitBind, |
179 | fExplicitBindToNativeImage, |
180 | &pPrivAsm); |
181 | } |
182 | |
183 | pResult->SetHRBindResult(hr); |
184 | if (SUCCEEDED(hr)) |
185 | { |
186 | _ASSERTE(pPrivAsm != nullptr); |
187 | |
188 | result = BINDER_SPACE::GetAssemblyFromPrivAssemblyFast(pPrivAsm.Extract()); |
189 | _ASSERTE(result != nullptr); |
190 | |
191 | pResult->Init(result); |
192 | } |
193 | else if (FAILED(hr) && (fThrowOnFileNotFound || (!Assembly::FileNotFound(hr)))) |
194 | { |
195 | ThrowLoadError(this, hr); |
196 | } |
197 | } |
198 | |
199 | |
200 | STDAPI BinderAcquirePEImage(LPCWSTR wszAssemblyPath, |
201 | PEImage **ppPEImage, |
202 | PEImage **ppNativeImage, |
203 | BOOL fExplicitBindToNativeImage) |
204 | { |
205 | HRESULT hr = S_OK; |
206 | |
207 | _ASSERTE(ppPEImage != NULL); |
208 | |
209 | EX_TRY |
210 | { |
211 | PEImageHolder pImage = NULL; |
212 | PEImageHolder pNativeImage = NULL; |
213 | |
214 | #ifdef FEATURE_PREJIT |
215 | // fExplicitBindToNativeImage is set on Phone when we bind to a list of native images and have no IL on device for an assembly |
216 | if (fExplicitBindToNativeImage) |
217 | { |
218 | pNativeImage = PEImage::OpenImage(wszAssemblyPath, MDInternalImport_TrustedNativeImage); |
219 | |
220 | // Make sure that the IL image can be opened if the native image is not available. |
221 | hr=pNativeImage->TryOpenFile(); |
222 | if (FAILED(hr)) |
223 | { |
224 | goto Exit; |
225 | } |
226 | } |
227 | else |
228 | #endif |
229 | { |
230 | pImage = PEImage::OpenImage(wszAssemblyPath, MDInternalImport_Default); |
231 | |
232 | // Make sure that the IL image can be opened if the native image is not available. |
233 | hr=pImage->TryOpenFile(); |
234 | if (FAILED(hr)) |
235 | { |
236 | goto Exit; |
237 | } |
238 | } |
239 | |
240 | if (pImage) |
241 | *ppPEImage = pImage.Extract(); |
242 | |
243 | if (ppNativeImage) |
244 | *ppNativeImage = pNativeImage.Extract(); |
245 | } |
246 | EX_CATCH_HRESULT(hr); |
247 | |
248 | Exit: |
249 | return hr; |
250 | } |
251 | |
252 | STDAPI BinderHasNativeHeader(PEImage *pPEImage, BOOL* result) |
253 | { |
254 | HRESULT hr = S_OK; |
255 | |
256 | _ASSERTE(pPEImage != NULL); |
257 | _ASSERTE(result != NULL); |
258 | |
259 | EX_TRY |
260 | { |
261 | *result = pPEImage->HasNativeHeader(); |
262 | } |
263 | EX_CATCH_HRESULT(hr); |
264 | |
265 | if (FAILED(hr)) |
266 | { |
267 | *result = false; |
268 | |
269 | #if defined(FEATURE_PAL) |
270 | // PAL_LOADLoadPEFile may fail while loading IL masquerading as NI. |
271 | // This will result in a ThrowHR(E_FAIL). Suppress the error. |
272 | if(hr == E_FAIL) |
273 | { |
274 | hr = S_OK; |
275 | } |
276 | #endif // defined(FEATURE_PAL) |
277 | } |
278 | |
279 | return hr; |
280 | } |
281 | |
282 | STDAPI BinderAcquireImport(PEImage *pPEImage, |
283 | IMDInternalImport **ppIAssemblyMetaDataImport, |
284 | DWORD *pdwPAFlags, |
285 | BOOL bNativeImage) |
286 | { |
287 | HRESULT hr = S_OK; |
288 | |
289 | _ASSERTE(pPEImage != NULL); |
290 | _ASSERTE(ppIAssemblyMetaDataImport != NULL); |
291 | _ASSERTE(pdwPAFlags != NULL); |
292 | |
293 | EX_TRY |
294 | { |
295 | PEImageLayoutHolder pLayout(pPEImage->GetLayout(PEImageLayout::LAYOUT_ANY,PEImage::LAYOUT_CREATEIFNEEDED)); |
296 | |
297 | // CheckCorHeader includes check of NT headers too |
298 | if (!pLayout->CheckCorHeader()) |
299 | IfFailGo(COR_E_ASSEMBLYEXPECTED); |
300 | |
301 | if (!pLayout->CheckFormat()) |
302 | IfFailGo(COR_E_BADIMAGEFORMAT); |
303 | |
304 | if (bNativeImage && pPEImage->IsNativeILILOnly()) |
305 | { |
306 | pPEImage->GetNativeILPEKindAndMachine(&pdwPAFlags[0], &pdwPAFlags[1]); |
307 | } |
308 | else |
309 | { |
310 | pPEImage->GetPEKindAndMachine(&pdwPAFlags[0], &pdwPAFlags[1]); |
311 | } |
312 | |
313 | *ppIAssemblyMetaDataImport = pPEImage->GetMDImport(); |
314 | if (!*ppIAssemblyMetaDataImport) |
315 | { |
316 | // Some native images don't contain metadata, to reduce size |
317 | if (!bNativeImage) |
318 | IfFailGo(COR_E_BADIMAGEFORMAT); |
319 | } |
320 | else |
321 | (*ppIAssemblyMetaDataImport)->AddRef(); |
322 | } |
323 | EX_CATCH_HRESULT(hr); |
324 | ErrExit: |
325 | return hr; |
326 | } |
327 | |
328 | HRESULT BaseAssemblySpec::ParseName() |
329 | { |
330 | CONTRACTL |
331 | { |
332 | INSTANCE_CHECK; |
333 | GC_TRIGGERS; |
334 | NOTHROW; |
335 | INJECT_FAULT(return E_OUTOFMEMORY;); |
336 | } |
337 | CONTRACTL_END; |
338 | |
339 | if (!m_pAssemblyName) |
340 | return S_OK; |
341 | |
342 | HRESULT hr = S_OK; |
343 | |
344 | EX_TRY |
345 | { |
346 | NewHolder<BINDER_SPACE::AssemblyIdentityUTF8> pAssemblyIdentity; |
347 | AppDomain *pDomain = ::GetAppDomain(); |
348 | _ASSERTE(pDomain); |
349 | |
350 | BINDER_SPACE::ApplicationContext *pAppContext = NULL; |
351 | IUnknown *pIUnknownBinder = pDomain->GetFusionContext(); |
352 | |
353 | if (pIUnknownBinder != NULL) |
354 | { |
355 | #if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) |
356 | if (pDomain->GetFusionContext() != pDomain->GetTPABinderContext()) |
357 | { |
358 | pAppContext = (static_cast<CLRPrivBinderAssemblyLoadContext *>(static_cast<ICLRPrivBinder*>(pIUnknownBinder)))->GetAppContext(); |
359 | } |
360 | else |
361 | #endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) |
362 | { |
363 | pAppContext = (static_cast<CLRPrivBinderCoreCLR *>(pIUnknownBinder))->GetAppContext(); |
364 | } |
365 | } |
366 | |
367 | hr = CCoreCLRBinderHelper::GetAssemblyIdentity(m_pAssemblyName, pAppContext, pAssemblyIdentity); |
368 | |
369 | if (FAILED(hr)) |
370 | { |
371 | m_ownedFlags |= BAD_NAME_OWNED; |
372 | IfFailThrow(hr); |
373 | } |
374 | |
375 | SetName(pAssemblyIdentity->GetSimpleNameUTF8()); |
376 | |
377 | if (pAssemblyIdentity->Have(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_VERSION)) |
378 | { |
379 | m_context.usMajorVersion = (USHORT)pAssemblyIdentity->m_version.GetMajor(); |
380 | m_context.usMinorVersion = (USHORT)pAssemblyIdentity->m_version.GetMinor(); |
381 | m_context.usBuildNumber = (USHORT)pAssemblyIdentity->m_version.GetBuild(); |
382 | m_context.usRevisionNumber = (USHORT)pAssemblyIdentity->m_version.GetRevision(); |
383 | } |
384 | |
385 | if (pAssemblyIdentity->Have(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_CULTURE)) |
386 | { |
387 | if (!pAssemblyIdentity->m_cultureOrLanguage.IsEmpty()) |
388 | SetCulture(pAssemblyIdentity->GetCultureOrLanguageUTF8()); |
389 | else |
390 | SetCulture("" ); |
391 | } |
392 | |
393 | if (pAssemblyIdentity-> |
394 | Have(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY_TOKEN) || |
395 | pAssemblyIdentity->Have(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY)) |
396 | { |
397 | m_pbPublicKeyOrToken = const_cast<BYTE *>(pAssemblyIdentity->GetPublicKeyOrTokenArray()); |
398 | m_cbPublicKeyOrToken = pAssemblyIdentity->m_publicKeyOrTokenBLOB.GetSize(); |
399 | |
400 | if (pAssemblyIdentity->Have(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY)) |
401 | { |
402 | m_dwFlags |= afPublicKey; |
403 | } |
404 | } |
405 | else if (pAssemblyIdentity-> |
406 | Have(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY_TOKEN_NULL)) |
407 | { |
408 | m_pbPublicKeyOrToken = const_cast<BYTE *>(pAssemblyIdentity->GetPublicKeyOrTokenArray()); |
409 | m_cbPublicKeyOrToken = 0; |
410 | } |
411 | else |
412 | { |
413 | m_pbPublicKeyOrToken = NULL; |
414 | m_cbPublicKeyOrToken = 0; |
415 | } |
416 | |
417 | if (pAssemblyIdentity-> |
418 | Have(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_PROCESSOR_ARCHITECTURE)) |
419 | { |
420 | switch (pAssemblyIdentity->m_kProcessorArchitecture) |
421 | { |
422 | case peI386: |
423 | m_dwFlags |= afPA_x86; |
424 | break; |
425 | case peIA64: |
426 | m_dwFlags |= afPA_IA64; |
427 | break; |
428 | case peAMD64: |
429 | m_dwFlags |= afPA_AMD64; |
430 | break; |
431 | case peARM: |
432 | m_dwFlags |= afPA_ARM; |
433 | break; |
434 | case peMSIL: |
435 | m_dwFlags |= afPA_MSIL; |
436 | break; |
437 | default: |
438 | IfFailThrow(FUSION_E_INVALID_NAME); |
439 | } |
440 | } |
441 | |
442 | |
443 | if (pAssemblyIdentity-> |
444 | Have(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_RETARGETABLE)) |
445 | { |
446 | m_dwFlags |= afRetargetable; |
447 | } |
448 | |
449 | if (pAssemblyIdentity-> |
450 | Have(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_CONTENT_TYPE)) |
451 | { |
452 | DWORD dwContentType = pAssemblyIdentity->m_kContentType; |
453 | |
454 | _ASSERTE((dwContentType == AssemblyContentType_Default) || (dwContentType == AssemblyContentType_WindowsRuntime)); |
455 | if (dwContentType == AssemblyContentType_WindowsRuntime) |
456 | { |
457 | m_dwFlags |= afContentType_WindowsRuntime; |
458 | } |
459 | } |
460 | |
461 | CloneFields(); |
462 | } |
463 | EX_CATCH_HRESULT(hr); |
464 | |
465 | return hr; |
466 | } |
467 | |
468 | #endif // DACCESS_COMPILE |
469 | |
470 | VOID BaseAssemblySpec::GetFileOrDisplayName(DWORD flags, SString &result) const |
471 | { |
472 | CONTRACTL |
473 | { |
474 | INSTANCE_CHECK; |
475 | THROWS; |
476 | INJECT_FAULT(ThrowOutOfMemory()); |
477 | PRECONDITION(CheckValue(result)); |
478 | PRECONDITION(result.IsEmpty()); |
479 | } |
480 | CONTRACTL_END; |
481 | |
482 | if (m_wszCodeBase) |
483 | { |
484 | result.Set(m_wszCodeBase); |
485 | return; |
486 | } |
487 | |
488 | if (flags==0) |
489 | flags=ASM_DISPLAYF_FULL; |
490 | |
491 | BINDER_SPACE::AssemblyIdentity assemblyIdentity; |
492 | SString tmpString; |
493 | |
494 | tmpString.SetUTF8(m_pAssemblyName); |
495 | |
496 | if ((m_ownedFlags & BAD_NAME_OWNED) != 0) |
497 | { |
498 | // Can't do anything with a broken name |
499 | tmpString.ConvertToUnicode(result); |
500 | return; |
501 | } |
502 | else |
503 | { |
504 | tmpString.ConvertToUnicode(assemblyIdentity.m_simpleName); |
505 | assemblyIdentity.SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_SIMPLE_NAME); |
506 | } |
507 | |
508 | if( flags & ASM_DISPLAYF_VERSION && m_context.usMajorVersion != 0xFFFF) |
509 | { |
510 | assemblyIdentity.m_version.SetFeatureVersion(m_context.usMajorVersion, |
511 | m_context.usMinorVersion); |
512 | assemblyIdentity.m_version.SetServiceVersion(m_context.usBuildNumber, |
513 | m_context.usRevisionNumber); |
514 | assemblyIdentity.SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_VERSION); |
515 | } |
516 | |
517 | if(flags & ASM_DISPLAYF_CULTURE) |
518 | { |
519 | assemblyIdentity.SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_CULTURE); |
520 | if ((m_context.szLocale != NULL) && (m_context.szLocale[0] != 0)) |
521 | { |
522 | tmpString.SetUTF8(m_context.szLocale); |
523 | tmpString.ConvertToUnicode(assemblyIdentity.m_cultureOrLanguage); |
524 | } |
525 | } |
526 | |
527 | if(flags & ASM_DISPLAYF_PUBLIC_KEY_TOKEN) |
528 | { |
529 | if (m_cbPublicKeyOrToken) |
530 | { |
531 | assemblyIdentity.SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY_TOKEN); |
532 | if(IsAfPublicKeyToken(m_dwFlags)) |
533 | { |
534 | assemblyIdentity.m_publicKeyOrTokenBLOB.Set(m_pbPublicKeyOrToken, |
535 | m_cbPublicKeyOrToken); |
536 | } |
537 | else |
538 | { |
539 | DWORD cbToken = 0; |
540 | StrongNameBufferHolder<BYTE> pbToken; |
541 | |
542 | // Try to get the strong name |
543 | if (!StrongNameTokenFromPublicKey(m_pbPublicKeyOrToken, |
544 | m_cbPublicKeyOrToken, |
545 | &pbToken, |
546 | &cbToken)) |
547 | { |
548 | // Throw an exception with details on what went wrong |
549 | COMPlusThrowHR(StrongNameErrorInfo()); |
550 | } |
551 | |
552 | assemblyIdentity.m_publicKeyOrTokenBLOB.Set(pbToken, cbToken); |
553 | } |
554 | } |
555 | else |
556 | { |
557 | assemblyIdentity. |
558 | SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY_TOKEN_NULL); |
559 | } |
560 | } |
561 | |
562 | if ((flags & ASM_DISPLAYF_PROCESSORARCHITECTURE) && (m_dwFlags & afPA_Mask)) |
563 | { |
564 | assemblyIdentity. |
565 | SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_PROCESSOR_ARCHITECTURE); |
566 | |
567 | if (m_dwFlags & afPA_MSIL) |
568 | assemblyIdentity.m_kProcessorArchitecture = peMSIL; |
569 | else if (m_dwFlags & afPA_x86) |
570 | assemblyIdentity.m_kProcessorArchitecture = peI386; |
571 | else if (m_dwFlags & afPA_IA64) |
572 | assemblyIdentity.m_kProcessorArchitecture = peIA64; |
573 | else if (m_dwFlags & afPA_AMD64) |
574 | assemblyIdentity.m_kProcessorArchitecture = peAMD64; |
575 | else if (m_dwFlags & afPA_ARM) |
576 | assemblyIdentity.m_kProcessorArchitecture = peARM; |
577 | } |
578 | |
579 | if ((flags & ASM_DISPLAYF_RETARGET) && (m_dwFlags & afRetargetable)) |
580 | { |
581 | assemblyIdentity.SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_RETARGETABLE); |
582 | } |
583 | |
584 | if ((flags & ASM_DISPLAYF_CONTENT_TYPE) && (m_dwFlags & afContentType_Mask) == afContentType_WindowsRuntime) |
585 | { |
586 | assemblyIdentity.SetHave(BINDER_SPACE::AssemblyIdentity::IDENTITY_FLAG_CONTENT_TYPE); |
587 | assemblyIdentity.m_kContentType = AssemblyContentType_WindowsRuntime; |
588 | } |
589 | |
590 | IfFailThrow(BINDER_SPACE::TextualIdentityParser::ToString(&assemblyIdentity, |
591 | assemblyIdentity.m_dwIdentityFlags, |
592 | result)); |
593 | } |
594 | |
595 | |
596 | |