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// BaseAssemblySpec.cpp
7//
8// Implements the BaseAssemblySpec class
9//
10
11
12// ============================================================
13
14#include "common.h"
15#include "thekey.h"
16
17VOID BaseAssemblySpec::CloneFieldsToStackingAllocator( StackingAllocator* alloc)
18{
19 CONTRACTL
20 {
21 INSTANCE_CHECK;
22 THROWS;
23 GC_TRIGGERS;
24 MODE_ANY;
25 INJECT_FAULT(ThrowOutOfMemory(););
26 }
27 CONTRACTL_END
28
29#if _DEBUG
30 DWORD hash = Hash();
31#endif
32
33 if ((~m_ownedFlags & NAME_OWNED) &&
34 m_pAssemblyName) {
35 S_UINT32 len = S_UINT32((DWORD) strlen(m_pAssemblyName)) + S_UINT32(1);
36 if(len.IsOverflow()) COMPlusThrowHR(COR_E_OVERFLOW);
37 LPSTR temp = (LPSTR)alloc->Alloc(len);
38 strcpy_s(temp, len.Value(), m_pAssemblyName);
39 m_pAssemblyName = temp;
40 }
41
42 if ((~m_ownedFlags & PUBLIC_KEY_OR_TOKEN_OWNED) &&
43 m_pbPublicKeyOrToken && m_cbPublicKeyOrToken > 0) {
44 BYTE *temp = (BYTE *)alloc->Alloc(S_UINT32(m_cbPublicKeyOrToken)) ;
45 memcpy(temp, m_pbPublicKeyOrToken, m_cbPublicKeyOrToken);
46 m_pbPublicKeyOrToken = temp;
47 }
48
49 if ((~m_ownedFlags & LOCALE_OWNED) &&
50 m_context.szLocale) {
51 S_UINT32 len = S_UINT32((DWORD) strlen(m_context.szLocale)) + S_UINT32(1);
52 if(len.IsOverflow()) COMPlusThrowHR(COR_E_OVERFLOW);
53 LPSTR temp = (char *)alloc->Alloc(len) ;
54 strcpy_s(temp, len.Value(), m_context.szLocale);
55 m_context.szLocale = temp;
56 }
57
58 if ((~m_ownedFlags & CODEBASE_OWNED) &&
59 m_wszCodeBase) {
60 S_UINT32 len = S_UINT32((DWORD) wcslen(m_wszCodeBase)) + S_UINT32(1);
61 if(len.IsOverflow()) COMPlusThrowHR(COR_E_OVERFLOW);
62 LPWSTR temp = (LPWSTR)alloc->Alloc(len*S_UINT32(sizeof(WCHAR)));
63 wcscpy_s(temp, len.Value(), m_wszCodeBase);
64 m_wszCodeBase = temp;
65 }
66
67 if ((~m_ownedFlags & WINRT_TYPE_NAME_OWNED)) {
68 if (m_szWinRtTypeNamespace)
69 {
70 S_UINT32 len = S_UINT32((DWORD) strlen(m_szWinRtTypeNamespace)) + S_UINT32(1);
71 if(len.IsOverflow()) COMPlusThrowHR(COR_E_OVERFLOW);
72 LPSTR temp = (LPSTR)alloc->Alloc(len*S_UINT32(sizeof(CHAR)));
73 strcpy_s(temp, len.Value(), m_szWinRtTypeNamespace);
74 m_szWinRtTypeNamespace = temp;
75 }
76
77 if (m_szWinRtTypeClassName)
78 {
79 S_UINT32 len = S_UINT32((DWORD) strlen(m_szWinRtTypeClassName)) + S_UINT32(1);
80 if(len.IsOverflow()) COMPlusThrowHR(COR_E_OVERFLOW);
81 LPSTR temp = (LPSTR)alloc->Alloc(len*S_UINT32(sizeof(CHAR)));
82 strcpy_s(temp, len.Value(), m_szWinRtTypeClassName);
83 m_szWinRtTypeClassName = temp;
84 }
85 }
86
87 _ASSERTE(hash == Hash());
88
89}
90
91#ifndef DACCESS_COMPILE
92BOOL BaseAssemblySpec::IsMscorlib()
93{
94 CONTRACTL
95 {
96 THROWS;
97 INSTANCE_CHECK;
98 GC_TRIGGERS;
99 MODE_ANY;
100 INJECT_FAULT(COMPlusThrowOM(););
101 }
102 CONTRACTL_END;
103 if (m_pAssemblyName == NULL)
104 {
105 LPCWSTR file = GetCodeBase();
106 if (file)
107 {
108 StackSString path(file);
109 PEAssembly::UrlToPath(path);
110 return SystemDomain::System()->IsBaseLibrary(path);
111 }
112 return FALSE;
113 }
114
115 _ASSERTE(strlen(g_psBaseLibraryName) == CoreLibNameLen);
116
117 // <TODO>More of bug 213471</TODO>
118 size_t iNameLen = strlen(m_pAssemblyName);
119 return ( (iNameLen >= CoreLibNameLen) &&
120 ( (!stricmpUTF8(m_pAssemblyName, g_psBaseLibrary)) ||
121 ( (!SString::_strnicmp(m_pAssemblyName, g_psBaseLibraryName, CoreLibNameLen)) &&
122 ( (iNameLen == CoreLibNameLen) || (m_pAssemblyName[CoreLibNameLen] == ',') ) ) ) );
123}
124
125BOOL BaseAssemblySpec::IsAssemblySpecForMscorlib()
126{
127 CONTRACTL
128 {
129 NOTHROW;
130 INSTANCE_CHECK;
131 GC_NOTRIGGER;
132 MODE_ANY;
133 PRECONDITION(strlen(g_psBaseLibraryName) == CoreLibNameLen);
134 }
135 CONTRACTL_END;
136
137 BOOL fIsAssemblySpecForMscorlib = FALSE;
138
139 if (m_pAssemblyName)
140 {
141 size_t iNameLen = strlen(m_pAssemblyName);
142 fIsAssemblySpecForMscorlib = ( (iNameLen >= CoreLibNameLen) &&
143 ( (!_stricmp(m_pAssemblyName, g_psBaseLibrary)) ||
144 ( (!_strnicmp(m_pAssemblyName, g_psBaseLibraryName, CoreLibNameLen)) &&
145 ( (iNameLen == CoreLibNameLen) || (m_pAssemblyName[CoreLibNameLen] == ',') ) ) ) );
146 }
147
148 return fIsAssemblySpecForMscorlib;
149}
150
151#define MSCORLIB_PUBLICKEY g_rbTheSilverlightPlatformKey
152
153
154// A satellite assembly for mscorlib is named "mscorlib.resources" or
155// mscorlib.debug.resources.dll and uses the same public key as mscorlib.
156// It does not necessarily have the same version, and the Culture will
157// always be set to something like "jp-JP".
158BOOL BaseAssemblySpec::IsMscorlibSatellite()
159{
160 CONTRACTL
161 {
162 THROWS;
163 INSTANCE_CHECK;
164 GC_TRIGGERS;
165 MODE_ANY;
166 INJECT_FAULT(COMPlusThrowOM(););
167 }
168 CONTRACTL_END;
169
170 if (m_pAssemblyName == NULL)
171 {
172 LPCWSTR file = GetCodeBase();
173 if (file)
174 {
175 StackSString path(file);
176 PEAssembly::UrlToPath(path);
177 return SystemDomain::System()->IsBaseLibrarySatellite(path);
178 }
179 return FALSE;
180 }
181
182 _ASSERTE(strlen(g_psBaseLibrarySatelliteAssemblyName) == CoreLibSatelliteNameLen);
183
184 // <TODO>More of bug 213471</TODO>
185 size_t iNameLen = strlen(m_pAssemblyName);
186
187 // we allow name to be of the form mscorlib.resources.dll only
188 BOOL r = ( (m_cbPublicKeyOrToken == sizeof(MSCORLIB_PUBLICKEY)) &&
189 (iNameLen >= CoreLibSatelliteNameLen) &&
190 (!SString::_strnicmp(m_pAssemblyName, g_psBaseLibrarySatelliteAssemblyName, CoreLibSatelliteNameLen)) &&
191 ( (iNameLen == CoreLibSatelliteNameLen) || (m_pAssemblyName[CoreLibSatelliteNameLen] == ',') ) );
192
193 r = r && ( memcmp(m_pbPublicKeyOrToken,MSCORLIB_PUBLICKEY,sizeof(MSCORLIB_PUBLICKEY)) == 0);
194
195 return r;
196}
197
198VOID BaseAssemblySpec::ConvertPublicKeyToToken()
199{
200 CONTRACTL
201 {
202 INSTANCE_CHECK;
203 THROWS;
204 GC_NOTRIGGER;
205 MODE_ANY;
206 PRECONDITION(HasPublicKey());
207 }
208 CONTRACTL_END;
209
210 StrongNameBufferHolder<BYTE> pbPublicKeyToken;
211 DWORD cbPublicKeyToken;
212 if (!StrongNameTokenFromPublicKey(m_pbPublicKeyOrToken,
213 m_cbPublicKeyOrToken,
214 &pbPublicKeyToken,
215 &cbPublicKeyToken))
216 ThrowHR(StrongNameErrorInfo());
217
218 BYTE *temp = new BYTE [cbPublicKeyToken];
219 memcpy(temp, pbPublicKeyToken, cbPublicKeyToken);
220
221 if (m_ownedFlags & PUBLIC_KEY_OR_TOKEN_OWNED)
222 delete [] m_pbPublicKeyOrToken;
223 else
224 m_ownedFlags |= PUBLIC_KEY_OR_TOKEN_OWNED;
225
226 m_pbPublicKeyOrToken = temp;
227 m_cbPublicKeyOrToken = cbPublicKeyToken;
228 m_dwFlags &= ~afPublicKey;
229}
230
231// Similar to BaseAssemblySpec::CompareEx, but allows the ref to be partially specified
232// Returns TRUE if ref matches def, FALSE otherwise.
233//
234// static
235BOOL BaseAssemblySpec::CompareRefToDef(const BaseAssemblySpec *pRef, const BaseAssemblySpec *pDef)
236{
237 WRAPPER_NO_CONTRACT;
238
239 if(pRef->m_wszCodeBase || pDef->m_wszCodeBase)
240 {
241 if(!pRef->m_wszCodeBase || !pDef->m_wszCodeBase)
242 return FALSE;
243
244 return wcscmp(pRef->m_wszCodeBase,(pDef->m_wszCodeBase)) == 0;
245 }
246
247 // Compare fields
248
249 //
250 // name is non-optional
251 //
252 if (pRef->m_pAssemblyName != pDef->m_pAssemblyName
253 && (pRef->m_pAssemblyName == NULL || pDef->m_pAssemblyName == NULL
254 || CompareStrings(pRef->m_pAssemblyName, pDef->m_pAssemblyName)))
255 {
256 return FALSE;
257 }
258
259 //
260 // public key [token] is non-optional
261 //
262 if (pRef->m_cbPublicKeyOrToken != pDef->m_cbPublicKeyOrToken
263 || memcmp(pRef->m_pbPublicKeyOrToken, pDef->m_pbPublicKeyOrToken, pRef->m_cbPublicKeyOrToken))
264 {
265 return FALSE;
266 }
267
268 //
269 // flags are non-optional, except processor architecture, content type, and debuggable attribute bits
270 //
271 DWORD dwFlagsMask = ~(afPA_FullMask | afContentType_Mask | afDebuggableAttributeMask);
272 if ((pRef->m_dwFlags & dwFlagsMask) != (pDef->m_dwFlags & dwFlagsMask))
273 return FALSE;
274
275 // To match Fusion behavior, we ignore processor architecture (GetAssemblyNameRefFromMDImport
276 // does not look at architecture part of the flags, and having processor architecture in
277 // InternalsVisibleTo attribute causess META_E_CA_BAD_FRIENDS_ARGS exception).
278 // Content type is optional in pRef.
279 if (!IsAfContentType_Default(pRef->m_dwFlags) && (pRef->m_dwFlags & afContentType_Mask) != (pDef->m_dwFlags & afContentType_Mask))
280 return FALSE;
281
282
283 //
284 // version info is optional in the ref
285 //
286 if (pRef->m_context.usMajorVersion != (USHORT) -1)
287 {
288 if (pRef->m_context.usMajorVersion != pDef->m_context.usMajorVersion)
289 return FALSE;
290
291 if (pRef->m_context.usMinorVersion != (USHORT) -1)
292 {
293 if (pRef->m_context.usMinorVersion != pDef->m_context.usMinorVersion)
294 return FALSE;
295
296 if (pRef->m_context.usBuildNumber != (USHORT) -1)
297 {
298 if (pRef->m_context.usBuildNumber != pDef->m_context.usBuildNumber)
299 return FALSE;
300
301 if (pRef->m_context.usRevisionNumber != (USHORT) -1)
302 {
303 if (pRef->m_context.usRevisionNumber != pDef->m_context.usRevisionNumber)
304 return FALSE;
305 }
306 }
307 }
308 }
309
310 //
311 // locale info is optional in the ref
312 //
313 if ((pRef->m_context.szLocale != NULL)
314 && (pRef->m_context.szLocale != pDef->m_context.szLocale)
315 && strcmp(pRef->m_context.szLocale, pDef->m_context.szLocale))
316 {
317 return FALSE;
318 }
319
320 return TRUE;
321}
322
323// static
324BOOL BaseAssemblySpec::RefMatchesDef(const BaseAssemblySpec* pRef, const BaseAssemblySpec* pDef)
325{
326 CONTRACTL
327 {
328 THROWS;
329 GC_NOTRIGGER;
330 MODE_ANY;
331 PRECONDITION(pRef->GetName()!=NULL && pDef->GetName()!=NULL);
332 }
333 CONTRACTL_END;
334
335 if (pRef->IsStrongNamed())
336 {
337 if (!pDef->IsStrongNamed())
338 return FALSE;
339
340 if(pRef->HasPublicKey())
341 {
342 // cannot use pRef->CompareEx(pDef) here because it does a full comparison
343 // and the ref may be partial.
344 return CompareRefToDef(pRef, pDef);
345 }
346 else
347 {
348 BaseAssemblySpec defCopy;
349 defCopy.CopyFrom(pDef);
350 defCopy.ConvertPublicKeyToToken();
351
352 return CompareRefToDef(pRef, &defCopy);
353 }
354 }
355 else
356 {
357 return (CompareStrings(pRef->GetName(), pDef->GetName())==0);
358 }
359}
360
361//===========================================================================================
362// This function may embed additional information, if required.
363//
364// For WinRT (ContentType=WindowsRuntime) assembly specs, this will embed the type name in
365// the IAssemblyName's ASM_NAME_NAME property; otherwise this just creates an IAssemblyName
366// for the provided assembly spec.
367
368void BaseAssemblySpec::GetEncodedName(SString & ssEncodedName) const
369{
370 CONTRACTL {
371 THROWS;
372 GC_NOTRIGGER;
373 MODE_ANY;
374 } CONTRACTL_END
375
376#ifdef FEATURE_COMINTEROP
377 if (IsContentType_WindowsRuntime() && GetWinRtTypeClassName() != NULL)
378 {
379 ssEncodedName.SetUTF8(GetName());
380 ssEncodedName.Append(SL(W("!")));
381 if (GetWinRtTypeNamespace() != NULL)
382 {
383 ssEncodedName.AppendUTF8(GetWinRtTypeNamespace());
384 ssEncodedName.Append(SL(W(".")));
385 }
386 ssEncodedName.AppendUTF8(GetWinRtTypeClassName());
387 }
388 else
389#endif
390 {
391 ssEncodedName.SetUTF8(m_pAssemblyName);
392 }
393}
394
395VOID BaseAssemblySpec::SetName(SString const & ssName)
396{
397 CONTRACTL
398 {
399 INSTANCE_CHECK;
400 GC_NOTRIGGER;
401 THROWS;
402 }
403 CONTRACTL_END;
404
405 if (m_ownedFlags & NAME_OWNED)
406 {
407 delete [] m_pAssemblyName;
408 m_ownedFlags &= ~NAME_OWNED;
409 }
410
411 m_pAssemblyName = NULL;
412
413 IfFailThrow(FString::ConvertUnicode_Utf8(ssName.GetUnicode(), & ((LPSTR &) m_pAssemblyName)));
414
415 m_ownedFlags |= NAME_OWNED;
416}
417
418HRESULT BaseAssemblySpec::Init(IAssemblyName *pName)
419{
420 CONTRACTL
421 {
422 NOTHROW;
423 GC_NOTRIGGER;
424 MODE_ANY;
425 }
426 CONTRACTL_END;
427
428 _ASSERTE(pName);
429
430 HRESULT hr;
431
432 // Fill out info from name, if we have it.
433
434 DWORD cbSize = 0;
435 hr=pName->GetProperty(ASM_NAME_NAME, NULL, &cbSize);
436 if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
437 hr=S_OK;
438 CQuickBytes qb;
439 LPWSTR pwName = (LPWSTR) qb.AllocNoThrow(cbSize);
440 if (!pwName)
441 return E_OUTOFMEMORY;
442
443 IfFailRet(pName->GetProperty(ASM_NAME_NAME, pwName, &cbSize));
444
445 m_pAssemblyName = NULL;
446
447 hr = FString::ConvertUnicode_Utf8(pwName, & ((LPSTR &) m_pAssemblyName));
448
449 if (FAILED(hr))
450 {
451 return hr;
452 }
453
454 m_ownedFlags |= NAME_OWNED;
455 }
456 IfFailRet(hr);
457
458 // Note: cascade checks so we don't set lower priority version #'s if higher ones are missing
459 cbSize = sizeof(m_context.usMajorVersion);
460 hr=pName->GetProperty(ASM_NAME_MAJOR_VERSION, &m_context.usMajorVersion, &cbSize);
461
462 if (hr!=S_OK || !cbSize)
463 m_context.usMajorVersion = (USHORT) -1;
464 else {
465 cbSize = sizeof(m_context.usMinorVersion);
466 hr=pName->GetProperty(ASM_NAME_MINOR_VERSION, &m_context.usMinorVersion, &cbSize);
467 }
468
469 if (hr!=S_OK || !cbSize)
470 m_context.usMinorVersion = (USHORT) -1;
471 else {
472 cbSize = sizeof(m_context.usBuildNumber);
473 pName->GetProperty(ASM_NAME_BUILD_NUMBER, &m_context.usBuildNumber, &cbSize);
474 }
475
476 if (hr!=S_OK || !cbSize)
477 m_context.usBuildNumber = (USHORT) -1;
478 else {
479 cbSize = sizeof(m_context.usRevisionNumber);
480 pName->GetProperty(ASM_NAME_REVISION_NUMBER, &m_context.usRevisionNumber, &cbSize);
481 }
482
483 if (hr!=S_OK || !cbSize)
484 m_context.usRevisionNumber = (USHORT) -1;
485
486 if (hr==E_INVALIDARG)
487 hr=S_FALSE;
488
489 IfFailRet(hr);
490
491 cbSize = 0;
492 hr = pName->GetProperty(ASM_NAME_CULTURE, NULL, &cbSize);
493
494 if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
495 LPWSTR pwName = (LPWSTR) alloca(cbSize);
496 IfFailRet(pName->GetProperty(ASM_NAME_CULTURE, pwName, &cbSize));
497
498 hr = FString::ConvertUnicode_Utf8(pwName, & ((LPSTR &) m_context.szLocale));
499
500 m_ownedFlags |= LOCALE_OWNED;
501 }
502
503 IfFailRet(hr);
504
505 m_dwFlags = 0;
506
507 cbSize = 0;
508 hr=pName->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, NULL, &cbSize);
509 if (hr== HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
510 m_pbPublicKeyOrToken = new (nothrow) BYTE[cbSize];
511 if (m_pbPublicKeyOrToken == NULL)
512 return E_OUTOFMEMORY;
513 m_cbPublicKeyOrToken = cbSize;
514 m_ownedFlags |= PUBLIC_KEY_OR_TOKEN_OWNED;
515 IfFailRet(pName->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, m_pbPublicKeyOrToken, &cbSize));
516 }
517 else {
518 if (hr!=E_INVALIDARG)
519 IfFailRet(hr);
520 hr=pName->GetProperty(ASM_NAME_PUBLIC_KEY, NULL, &cbSize);
521 if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
522 hr=S_OK;
523 // <TODO>@todo: we need to normalize this into a public key token so
524 // comparisons work correctly. But this involves binding to mscorsn.</TODO>
525 m_pbPublicKeyOrToken = new (nothrow) BYTE[cbSize];
526 if (m_pbPublicKeyOrToken == NULL)
527 return E_OUTOFMEMORY;
528 m_cbPublicKeyOrToken = cbSize;
529 m_dwFlags |= afPublicKey;
530 m_ownedFlags |= PUBLIC_KEY_OR_TOKEN_OWNED;
531 IfFailRet(pName->GetProperty(ASM_NAME_PUBLIC_KEY, m_pbPublicKeyOrToken, &cbSize));
532 }
533 else {
534 IfFailRet(hr);
535 hr= pName->GetProperty(ASM_NAME_NULL_PUBLIC_KEY, NULL, &cbSize);
536 if (hr!=S_OK)
537 hr=pName->GetProperty(ASM_NAME_NULL_PUBLIC_KEY_TOKEN, NULL, &cbSize);
538 if ( hr == S_OK ) {
539 m_pbPublicKeyOrToken = new (nothrow) BYTE[0];
540 if (m_pbPublicKeyOrToken == NULL)
541 return E_OUTOFMEMORY;
542 m_cbPublicKeyOrToken = 0;
543 m_ownedFlags |= PUBLIC_KEY_OR_TOKEN_OWNED;
544 }
545 if (hr==E_INVALIDARG)
546 hr=S_FALSE;
547 IfFailRet(hr);
548
549 }
550 }
551
552 // Recover the afRetargetable flag
553 BOOL bRetarget;
554 cbSize = sizeof(bRetarget);
555 hr = pName->GetProperty(ASM_NAME_RETARGET, &bRetarget, &cbSize);
556 if (hr == S_OK && cbSize != 0 && bRetarget)
557 m_dwFlags |= afRetargetable;
558
559 // Recover the Processor Architecture flags
560 PEKIND peKind;
561 cbSize = sizeof(PEKIND);
562 hr = pName->GetProperty(ASM_NAME_ARCHITECTURE, &peKind, &cbSize);
563 if ((hr == S_OK) && (cbSize != 0) && (peKind < (afPA_NoPlatform >> afPA_Shift)) && (peKind >= (afPA_MSIL >> afPA_Shift)))
564 m_dwFlags |= (((DWORD)peKind) << afPA_Shift);
565
566 cbSize = 0;
567 hr=pName->GetProperty(ASM_NAME_CODEBASE_URL, NULL, &cbSize);
568 if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
569 m_wszCodeBase = new (nothrow) WCHAR [ cbSize/sizeof(WCHAR) ];
570 if (m_wszCodeBase == NULL)
571 return E_OUTOFMEMORY;
572 m_ownedFlags |= CODE_BASE_OWNED;
573 IfFailRet(pName->GetProperty(ASM_NAME_CODEBASE_URL,
574 (void*)m_wszCodeBase, &cbSize));
575 }
576 else
577 IfFailRet(hr);
578
579 // Recover the Content Type enum
580 DWORD dwContentType;
581 cbSize = sizeof(dwContentType);
582 hr = pName->GetProperty(ASM_NAME_CONTENT_TYPE, &dwContentType, &cbSize);
583 if ((hr == S_OK) && (cbSize == sizeof(dwContentType)))
584 {
585 _ASSERTE((dwContentType == AssemblyContentType_Default) || (dwContentType == AssemblyContentType_WindowsRuntime));
586 if (dwContentType == AssemblyContentType_WindowsRuntime)
587 {
588 m_dwFlags |= afContentType_WindowsRuntime;
589 }
590 }
591
592 return S_OK;
593}
594
595HRESULT BaseAssemblySpec::CreateFusionName(
596 IAssemblyName **ppName,
597 BOOL fIncludeCodeBase/*=TRUE*/,
598 BOOL fMustBeBindable /*=FALSE*/) const
599{
600 CONTRACTL
601 {
602 NOTHROW;
603 GC_NOTRIGGER;
604 MODE_ANY;
605 }
606 CONTRACTL_END;
607
608 HRESULT hr = S_OK;
609
610 EX_TRY
611 {
612 IAssemblyName *pFusionAssemblyName = NULL;
613 LPWSTR pwLocale = NULL;
614 CQuickBytes qb;
615
616 NonVMComHolder< IAssemblyName > holder(NULL);
617
618 SmallStackSString ssAssemblyName;
619 fMustBeBindable ? GetEncodedName(ssAssemblyName) : GetName(ssAssemblyName);
620
621 IfFailGo(CreateAssemblyNameObject(&pFusionAssemblyName, ssAssemblyName.GetUnicode(), 0, NULL));
622
623 holder = pFusionAssemblyName;
624
625 if (m_context.usMajorVersion != (USHORT) -1) {
626 IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_MAJOR_VERSION,
627 &m_context.usMajorVersion,
628 sizeof(USHORT)));
629
630 if (m_context.usMinorVersion != (USHORT) -1) {
631 IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_MINOR_VERSION,
632 &m_context.usMinorVersion,
633 sizeof(USHORT)));
634
635 if (m_context.usBuildNumber != (USHORT) -1) {
636 IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_BUILD_NUMBER,
637 &m_context.usBuildNumber,
638 sizeof(USHORT)));
639
640 if (m_context.usRevisionNumber != (USHORT) -1)
641 IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_REVISION_NUMBER,
642 &m_context.usRevisionNumber,
643 sizeof(USHORT)));
644 }
645 }
646 }
647
648 if (m_context.szLocale) {
649 int pwLocaleLen = WszMultiByteToWideChar(CP_UTF8, 0, m_context.szLocale, -1, 0, 0);
650 if(pwLocaleLen == 0) {
651 IfFailGo(HRESULT_FROM_GetLastError());
652 } else if (pwLocaleLen > MAKE_MAX_LENGTH) {
653 IfFailGo(COR_E_OVERFLOW);
654 }
655 pwLocale = (LPWSTR) qb.AllocNoThrow((pwLocaleLen + 1) *sizeof(WCHAR));
656 if (!pwLocaleLen)
657 IfFailGo(E_OUTOFMEMORY);
658 if (!WszMultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
659 m_context.szLocale, -1, pwLocale, pwLocaleLen))
660 IfFailGo(HRESULT_FROM_GetLastError());
661 pwLocale[pwLocaleLen] = 0;
662
663 IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_CULTURE,
664 pwLocale,
665 (DWORD)(wcslen(pwLocale) + 1) * sizeof (WCHAR)));
666 }
667
668 if (m_pbPublicKeyOrToken) {
669 if (m_cbPublicKeyOrToken) {
670 if(m_dwFlags & afPublicKey) {
671 IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_PUBLIC_KEY,
672 m_pbPublicKeyOrToken, m_cbPublicKeyOrToken));
673 }
674 else {
675 IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_PUBLIC_KEY_TOKEN,
676 m_pbPublicKeyOrToken, m_cbPublicKeyOrToken));
677 }
678 }
679 else {
680 }
681 }
682
683
684 // Set the Processor Architecture (if any)
685 {
686 DWORD dwPEkind = (DWORD)PAIndex(m_dwFlags);
687 // Note: Value 0x07 = code:afPA_NoPlatform falls through
688 if ((dwPEkind >= peMSIL) && (dwPEkind <= peARM))
689 {
690 PEKIND peKind = (PEKIND)dwPEkind;
691 IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_ARCHITECTURE,
692 &peKind, sizeof(peKind)));
693 }
694 }
695
696 // Set the Content Type (if any)
697 {
698 if (IsAfContentType_WindowsRuntime(m_dwFlags))
699 {
700 DWORD dwContentType = AssemblyContentType_WindowsRuntime;
701 IfFailGo(pFusionAssemblyName->SetProperty(
702 ASM_NAME_CONTENT_TYPE,
703 &dwContentType,
704 sizeof(dwContentType)));
705 }
706 }
707
708 _ASSERTE(m_wszCodeBase == NULL);
709
710 *ppName = pFusionAssemblyName;
711
712 holder.SuppressRelease();
713 hr = S_OK;
714
715 ErrExit:
716 ;
717 }
718 EX_CATCH_HRESULT(hr);
719
720 return hr;
721}
722
723#endif // !DACCESS_COMPILE
724