HRESULT MicrosoftInstrumentationEngine::CTypeCreator::ParseMethodSignature()

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;
}