in src/InstrumentationEngine/AssemblyInjector.cpp [330:459]
HRESULT MicrosoftInstrumentationEngine::AssemblyInjector::ImportAssemblyRef(_In_ mdAssemblyRef sourceAssemblyRef, _Out_ mdToken *pTargetAssemblyScope)
{
HRESULT hr = S_OK;
IfFalseRet(sourceAssemblyRef != mdTokenNil && sourceAssemblyRef != mdAssemblyRefNil, E_FAIL);
TokenMap::const_iterator itr = m_assemblyRefMap.find(sourceAssemblyRef);
if (itr != m_assemblyRefMap.end())
{
*pTargetAssemblyScope = itr->second;
return hr;
}
CLogging::XmlDumpHelper dumpLogHelper(L"ImportAssemblyRef", 1);
dumpLogHelper.WriteUlongNode(L"token", sourceAssemblyRef);
ATL::CComPtr<IMetaDataAssemblyImport> pAssemblyImport;
IfFailRet(m_pSourceImport->QueryInterface(IID_IMetaDataAssemblyImport, reinterpret_cast<void**>(&pAssemblyImport)));
ATL::CComPtr<IMetaDataAssemblyImport> pTargetAssemblyImport;
IfFailRet(m_pTargetImport->QueryInterface(IID_IMetaDataAssemblyImport, reinterpret_cast<void**>(&pTargetAssemblyImport)));
const void* pbPublicKeyOrToken = nullptr;
ULONG cbPublicKeyOrToken = 0;
WCHAR szName[MAX_NAME] = { 0 };
ULONG cchName = 0;
const void* pbHashValue = nullptr;
ULONG cbHashValue = 0;
DWORD dwAssemblyRefFlags = 0;
IfFailRet(pAssemblyImport->GetAssemblyRefProps(sourceAssemblyRef,
&pbPublicKeyOrToken,
&cbPublicKeyOrToken,
szName,
_countof(szName),
&cchName,
nullptr,
&pbHashValue,
&cbHashValue,
&dwAssemblyRefFlags));
CMetadataEnumCloser<IMetaDataAssemblyImport> spHCorEnumTarget(pTargetAssemblyImport, nullptr);
mdAssemblyRef cur = mdAssemblyRefNil;
ULONG cTokens = 0;
while (S_OK == (hr = pTargetAssemblyImport->EnumAssemblyRefs(spHCorEnumTarget.Get(), &cur, 1, &cTokens)))
{
const void* pbPublicKeyOrTokenTarget = nullptr;
ULONG cbPublicKeyOrTokenTarget = 0;
WCHAR szNameTarget[MAX_NAME] = { 0 };
ULONG cchNameTarget = 0;
const void* pbHashValueTarget = nullptr;
ULONG cbHashValueTarget = 0;
DWORD dwAssemblyRefFlagsTarget = 0;
IfFailRet(pAssemblyImport->GetAssemblyRefProps(cur,
&pbPublicKeyOrTokenTarget,
&cbPublicKeyOrTokenTarget,
szNameTarget,
_countof(szName),
&cchNameTarget,
nullptr,
&pbHashValueTarget,
&cbHashValueTarget,
&dwAssemblyRefFlagsTarget));
if (wcscmp(szName, szNameTarget) == 0)
{
break;
}
}
IfFailRet(hr);
if (hr == S_OK)
{
*pTargetAssemblyScope = cur;
m_assemblyRefMap[sourceAssemblyRef] = *pTargetAssemblyScope;
dumpLogHelper.WriteStringNode(L"UseExistingRef", L"true");
dumpLogHelper.WriteUlongNode(L"targetToken", *pTargetAssemblyScope);
return hr;
}
// didn't find a matching ref - perhaps the reference is to the assembly we are Importing within?
mdAssembly targetAssembly = mdAssemblyNil;
IfFailRet(pTargetAssemblyImport->GetAssemblyFromScope(&targetAssembly));
const void* pbPublicKeyOrTokenTarget = nullptr;
ULONG cbPublicKeyOrTokenTarget = 0;
ULONG ulHashAlgIdTarget = 0;
WCHAR szNameTarget[MAX_NAME] = { 0 };
DWORD dwAssemblyFlagsTarget = 0;
IfFailRet(pTargetAssemblyImport->GetAssemblyProps(targetAssembly,
&pbPublicKeyOrTokenTarget,
&cbPublicKeyOrTokenTarget,
&ulHashAlgIdTarget,
szNameTarget,
_countof(szNameTarget),
&cchName,
nullptr,
&dwAssemblyFlagsTarget));
if (wcscmp(szName, szNameTarget) == 0)
{
*pTargetAssemblyScope = targetAssembly;
m_assemblyRefMap[sourceAssemblyRef] = *pTargetAssemblyScope;
dumpLogHelper.WriteStringNode(L"UseTarget", L"true");
dumpLogHelper.WriteUlongNode(L"targetToken", *pTargetAssemblyScope);
return S_OK;
}
// maybe the reference is to a contract assembly which is ultimately implemented by the assembly we are Importing into
// this is an ad-hoc list and isn't comprehensive
if (wcscmp(L"mscorlib", szNameTarget) == 0)
{
if (wcscmp(szName, L"System.Runtime") == 0 ||
wcscmp(szName, L"System.Collections") == 0 ||
wcscmp(szName, L"System.Console") == 0 ||
wcscmp(szName, L"System.Reflection") == 0
)
{
*pTargetAssemblyScope = targetAssembly;
m_assemblyRefMap[sourceAssemblyRef] = *pTargetAssemblyScope;
dumpLogHelper.WriteStringNode(L"ContractAssembly", L"true");
dumpLogHelper.WriteUlongNode(L"targetToken", *pTargetAssemblyScope);
return S_OK;
}
}
CLogging::LogError(_T("Adding new assembly refs not supported: %s"), szName);
return E_NOTIMPL;
}