HRESULT MicrosoftInstrumentationEngine::CInstruction::LogInstruction()

in src/InstrumentationEngine/Instruction.cpp [8:191]


HRESULT MicrosoftInstrumentationEngine::CInstruction::LogInstruction(bool ignoreTest)
{
    HRESULT hr = S_OK;

    tstring strIgnoreTestPrefix(ignoreTest ? _T("[TestIgnore] ") : _T(""));

    tstring strInstruction(strIgnoreTestPrefix);

    const size_t InstructionBufferSize = 64;
    WCHAR wszInstructionBuffer[InstructionBufferSize];

    ZeroMemory(wszInstructionBuffer, InstructionBufferSize);
    _snwprintf_s(
        wszInstructionBuffer,
        InstructionBufferSize,
        _TRUNCATE,
        _T("IL_%04x %s"),
        m_offset,
        s_ilOpcodeInfo[m_opcode].m_name);
    strInstruction.append(wszInstructionBuffer);

    CComPtr<IOperandInstruction> pOperand;
    if (SUCCEEDED(this->QueryInterface(__uuidof(IOperandInstruction), (LPVOID*)&pOperand)))
    {
        DWORD dwOperandSize = 0;
        IfFailRet(this->GetOperandLength(&dwOperandSize));

        if (dwOperandSize != 0)
        {
            CAutoVectorPtr<BYTE> pOperandValue;
            pOperandValue.Allocate(dwOperandSize);

            IfFailRet(pOperand->GetOperandValue(dwOperandSize, pOperandValue));

            ILOperandType operandType;
            IfFailRet(pOperand->GetOperandType(&operandType));

            ZeroMemory(wszInstructionBuffer, InstructionBufferSize);
            switch(operandType)
            {
            case ILOperandType_Byte:
                _snwprintf_s(
                    wszInstructionBuffer,
                    InstructionBufferSize,
                    _TRUNCATE,
                    _T(" 0x%x"),
                    *(BYTE*)(pOperandValue.m_p));
                break;
            case ILOperandType_Int:
                _snwprintf_s(
                    wszInstructionBuffer,
                    InstructionBufferSize,
                    _TRUNCATE,
                    _T(" 0x%x"),
                    *(DWORD*)(pOperandValue.m_p));
                break;
            case ILOperandType_UShort:
                _snwprintf_s(
                    wszInstructionBuffer,
                    InstructionBufferSize,
                    _TRUNCATE,
                    _T(" 0x%x"),
                    *(USHORT*)(pOperandValue.m_p));
                break;
            case ILOperandType_Long:
                // There is no format specifier for LONGLONG; use LARGE_INTEGER to break apart
                // the LONGLONG and format each part appropriately.
                LARGE_INTEGER value;
                value.QuadPart = *(LONGLONG*)(pOperandValue.m_p);
                if (value.u.HighPart != 0L)
                {
                    _snwprintf_s(
                        wszInstructionBuffer,
                        InstructionBufferSize,
                        _TRUNCATE,
                        _T(" 0x%x"),
                        value.u.HighPart);
                    strInstruction.append(wszInstructionBuffer);
                    ZeroMemory(wszInstructionBuffer, InstructionBufferSize);
                    _snwprintf_s(
                        wszInstructionBuffer,
                        InstructionBufferSize,
                        _TRUNCATE,
                        _T("%08x"),
                        value.u.LowPart);
                }
                else
                {
                    _snwprintf_s(
                        wszInstructionBuffer,
                        InstructionBufferSize,
                        _TRUNCATE,
                        _T(" 0x%x"),
                        value.u.LowPart);
                }
                break;
            case ILOperandType_Single:
                _snwprintf_s(
                    wszInstructionBuffer,
                    InstructionBufferSize,
                    _TRUNCATE,
                    _T(" 0x%f"),
                    *(float*)(pOperandValue.m_p));
                break;
            case ILOperandType_Double:
                _snwprintf_s(
                    wszInstructionBuffer,
                    InstructionBufferSize,
                    _TRUNCATE,
                    _T(" 0x%f"),
                    *(double*)(pOperandValue.m_p));
                break;
            case ILOperandType_Token:
                _snwprintf_s(
                    wszInstructionBuffer,
                    InstructionBufferSize,
                    _TRUNCATE,
                    _T(" 0x%08x"),
                    *(DWORD*)(pOperandValue.m_p));
                break;
            default:
                wcscpy_s(wszInstructionBuffer, InstructionBufferSize, _T(" (Invalid operand type)"));
                break;
            }
            strInstruction.append(wszInstructionBuffer);
        }
    }
    else
    {
        CComPtr<IBranchInstruction> pBranchInstruction;
        if (SUCCEEDED(this->QueryInterface(__uuidof(IBranchInstruction), (LPVOID*)&pBranchInstruction)))
        {
            CComPtr<IInstruction> pBranchTarget;
            IfFailRet(pBranchInstruction->GetBranchTarget(&pBranchTarget));

            DWORD targetOffset = 0;
            IfFailRet(pBranchTarget->GetOffset(&targetOffset));

            ZeroMemory(wszInstructionBuffer, InstructionBufferSize);
            _snwprintf_s(
                wszInstructionBuffer,
                InstructionBufferSize,
                _TRUNCATE,
                _T(" IL_%04x"),
                targetOffset);
            strInstruction.append(wszInstructionBuffer);
        }
        else
        {
            CComPtr<ISwitchInstruction> pSwitchInstruction;
            if (SUCCEEDED(this->QueryInterface(__uuidof(ISwitchInstruction), (LPVOID*)&pSwitchInstruction)))
            {
                DWORD branchCount = 0;
                IfFailRet(pSwitchInstruction->GetBranchCount(&branchCount));

                strInstruction.append(_T(" ("));
                for (DWORD i = 0; i < branchCount; i++)
                {
                    DWORD offset = 0;
                    IfFailRet(pSwitchInstruction->GetBranchOffset(i, &offset));

                    ZeroMemory(wszInstructionBuffer, InstructionBufferSize);
                    _snwprintf_s(
                        wszInstructionBuffer,
                        InstructionBufferSize,
                        _TRUNCATE,
                        _T("IL_%04x"),
                        offset);
                    strInstruction.append(wszInstructionBuffer);

                    if (i < branchCount - 1)
                    {
                        strInstruction.append(_T(","));
                    }
                }
                strInstruction.append(_T(")"));
            }
        }
    }

    CLogging::LogDumpMessage(_T("%s"), strInstruction.c_str());

    return hr;
}