/* static */ HRESULT Compatibility::Retarget(AssemblyName *pAssemblyName, AssemblyName **ppRetargetedAssemblyName, BOOL *pfIsRetargeted) { HRESULT hr = S_OK; BINDER_LOG_ENTER(W("Compatibility::Retarget")); IF_FALSE_GO(pAssemblyName != NULL); IF_FALSE_GO(ppRetargetedAssemblyName != NULL); BINDER_LOG_ASSEMBLY_NAME(W("source"), pAssemblyName); if (pfIsRetargeted) { *pfIsRetargeted = FALSE; } #ifdef FEATURE_CORESYSTEM // Apply retargeting only for strong-named culture neutral assemblies if (pAssemblyName->IsStronglyNamed() && pAssemblyName->GetDeNormalizedCulture().IsEmpty()) { ReleaseHolder<AssemblyName> pRetargetedAssemblyName; SString &simpleName = pAssemblyName->GetSimpleName(); AssemblyVersion *pAssemblyVersion = pAssemblyName->GetVersion(); SString publicKeyToken; TextualIdentityParser::BlobToHex(pAssemblyName->GetPublicKeyTokenBLOB(), publicKeyToken); // Perform linear search for matching assembly. Legacy Fusion also does that for (unsigned int i = 0; i < LENGTH_OF(arRetargetConfig); i++) { #ifdef FEATURE_LEGACYNETCF if (!RuntimeIsLegacyNetCF(0) && arRetargetConfig[i].fMangoOnly == TRUE) continue; #endif if (IsMatchingString(simpleName, arRetargetConfig[i].pwzSimpleName) && IsMatchingVersion(pAssemblyVersion, arRetargetConfig[i].pwzVersion) && IsMatchingString(publicKeyToken, arRetargetConfig[i].pwzPublicKeyToken)) { AssemblyVersion newAssemblyVersion; IF_FALSE_GO(newAssemblyVersion.SetVersion(arRetargetConfig[i].pwzNewVersion)); SAFE_NEW(pRetargetedAssemblyName, AssemblyName); if (arRetargetConfig[i].pwzNewSimpleName != NULL) { pRetargetedAssemblyName-> GetSimpleName().Set(arRetargetConfig[i].pwzNewSimpleName); } else { pRetargetedAssemblyName->GetSimpleName().Set(simpleName); } pRetargetedAssemblyName->SetVersion(&newAssemblyVersion); SBuffer newPublicKeyTokenBlob; SmallStackSString newPublicKeyToken(arRetargetConfig[i].pwzNewPublicKeyToken); TextualIdentityParser::HexToBlob(newPublicKeyToken, FALSE /* fValidateHex */, TRUE /* fIsToken */, newPublicKeyTokenBlob); pRetargetedAssemblyName->GetPublicKeyTokenBLOB().Set(newPublicKeyTokenBlob); BINDER_LOG_ASSEMBLY_NAME(W("retargeted"), pRetargetedAssemblyName); *ppRetargetedAssemblyName = pRetargetedAssemblyName.Extract(); if (pfIsRetargeted) { *pfIsRetargeted = TRUE; } GO_WITH_HRESULT(S_OK); } } // Create a clone without retargetable flag if (pAssemblyName->GetIsRetargetable()) { IF_FAIL_GO(pAssemblyName->Clone(&pRetargetedAssemblyName)); pRetargetedAssemblyName->SetIsRetargetable(FALSE); *ppRetargetedAssemblyName = pRetargetedAssemblyName.Extract(); } else { pAssemblyName->AddRef(); *ppRetargetedAssemblyName = pAssemblyName; } } else #endif // FEATURE_CORESYSTEM { pAssemblyName->AddRef(); *ppRetargetedAssemblyName = pAssemblyName; } Exit: BINDER_LOG_LEAVE_HR(W("Compatibility::Retarget"), hr); return hr; }
HRESULT CNodeFactory::GetPolicyVersion(LPCWSTR wzAssemblyName, LPCWSTR wzPublicKeyToken, LPCWSTR wzCulture, LPCWSTR wzVersionIn, LPWSTR *ppwzVersionOut) { HRESULT hr = S_OK; LISTNODE pos = NULL; LISTNODE posVer = NULL; LPCWSTR pwzCultureFormatted = NULL; CBindingRedir *pRedir = NULL; CAsmBindingInfo *pAsmInfo = NULL; if (!wzAssemblyName || !wzPublicKeyToken || !wzVersionIn || !ppwzVersionOut) { hr = E_INVALIDARG; goto Exit; } if (wzCulture && (!lstrcmpiW(wzCulture, CFG_CULTURE_NEUTRAL) || !lstrlenW(wzCulture))) { pwzCultureFormatted = NULL; } else { pwzCultureFormatted = wzCulture; } *ppwzVersionOut = NULL; pos = _listAsmInfo.GetHeadPosition(); while (pos) { pAsmInfo = _listAsmInfo.GetNext(pos); ASSERT(pAsmInfo); if ((!lstrcmpiW(wzAssemblyName, pAsmInfo->_pwzName) && (pAsmInfo->_pwzPublicKeyToken && !lstrcmpiW(wzPublicKeyToken, pAsmInfo->_pwzPublicKeyToken)) && ((pwzCultureFormatted && pAsmInfo->_pwzCulture && !lstrcmpiW(pwzCultureFormatted, pAsmInfo->_pwzCulture)) || (!pwzCultureFormatted && !pAsmInfo->_pwzCulture)))) { // Match found. // Look for matching version. posVer = (pAsmInfo->_listBindingRedir).GetHeadPosition(); while (posVer) { pRedir = (pAsmInfo->_listBindingRedir).GetNext(posVer); if (IsMatchingVersion(pRedir->_pwzVersionOld, wzVersionIn)) { // Match found *ppwzVersionOut = WSTRDupDynamic(pRedir->_pwzVersionNew); if (!*ppwzVersionOut) { hr = E_OUTOFMEMORY; goto Exit; } goto Exit; } } // We could break out of the loop here, but this prevents // multiple matches (ie. XML had many identical <dependentAssembly> // tags... } } // If we got here, we didn't find a match. Input Version == Output Version *ppwzVersionOut = WSTRDupDynamic(wzVersionIn); if (!*ppwzVersionOut) { hr = E_OUTOFMEMORY; goto Exit; } Exit: return hr; }