in src/InstrumentationEngine/TypeCreator.cpp [384:484]
HRESULT MicrosoftInstrumentationEngine::CTypeCreator::ParseMethodSignature(
_In_reads_bytes_(cbSignature) const BYTE* pSignature,
_In_ DWORD cbSignature,
_Out_opt_ ULONG* pCallingConvention,
_Out_opt_ IType** ppReturnType,
_Out_opt_ IEnumTypes** ppEnumParameterTypes,
_Out_opt_ ULONG* pcGenericTypeParameters,
_Out_opt_ ULONG* pcbRead
)
{
IfNullRetPointer(pSignature);
if (pCallingConvention)
{
*pCallingConvention = IMAGE_CEE_CS_CALLCONV_MAX;
}
if (ppReturnType)
{
*ppReturnType = nullptr;
}
if (ppEnumParameterTypes)
{
*ppEnumParameterTypes = nullptr;
}
if (pcGenericTypeParameters)
{
*pcGenericTypeParameters = 0;
}
if (pcbRead)
{
*pcbRead = 0;
}
HRESULT hr = S_OK;
ULONG cbRead = 0;
// Read the calling convention
ULONG callingConvention = IMAGE_CEE_CS_CALLCONV_MAX;
cbRead = CorSigUncompressData(pSignature, &callingConvention);
if ((callingConvention == IMAGE_CEE_CS_CALLCONV_MAX) ||
(callingConvention == IMAGE_CEE_CS_CALLCONV_FIELD) ||
(callingConvention == IMAGE_CEE_CS_CALLCONV_GENERICINST) ||
(callingConvention == IMAGE_CEE_CS_CALLCONV_LOCAL_SIG) ||
(callingConvention == IMAGE_CEE_CS_CALLCONV_PROPERTY))
{
CLogging::LogError(_T("Unexpected calling convention on method signature."));
return E_UNEXPECTED;
}
IfFailRet(cbSignature > cbRead ? S_OK : E_UNEXPECTED);
// Read number of generic type parameters
ULONG cGenericTypeParameters = 0;
if ((callingConvention & IMAGE_CEE_CS_CALLCONV_GENERIC) == IMAGE_CEE_CS_CALLCONV_GENERIC)
{
cbRead += CorSigUncompressData(pSignature + cbRead, &cGenericTypeParameters);
IfFailRet(cbSignature > cbRead ? S_OK : E_UNEXPECTED);
}
// Read number of parameters
ULONG cParameterTypes = 0;
cbRead += CorSigUncompressData(pSignature + cbRead, &cParameterTypes);
IfFailRet(cbSignature > cbRead ? S_OK : E_UNEXPECTED);
ULONG cbReadType;
// Read return type
CComPtr<IType> pReturnType;
IfFailRet(FromSignature(cbSignature - cbRead, pSignature + cbRead, &pReturnType, &cbReadType));
cbRead += cbReadType;
IfFailRet(cbSignature >= cbRead ? S_OK : E_UNEXPECTED);
// Read parameter types
CComPtr<IEnumTypes> pEnumParameterTypes;
IfFailRet(ParseTypeSequence(pSignature + cbRead, cbSignature - cbRead, cParameterTypes, &pEnumParameterTypes, &cbReadType));
cbRead += cbReadType;
IfFailRet(cbSignature >= cbRead ? S_OK : E_UNEXPECTED);
if (pCallingConvention)
{
*pCallingConvention = callingConvention;
}
if (ppReturnType)
{
*ppReturnType = pReturnType.Detach();
}
if (ppEnumParameterTypes)
{
*ppEnumParameterTypes = pEnumParameterTypes.Detach();
}
if (pcGenericTypeParameters)
{
*pcGenericTypeParameters = cGenericTypeParameters;
}
if (pcbRead)
{
*pcbRead = cbRead;
}
return S_OK;
}