HRESULT STDMETHODCALLTYPE CLiveExdiGdbSrvServer::Ioctl()

in Exdi/exdigdbsrv/ExdiGdbSrv/LiveExdiGdbSrvServer.cpp [649:767]


HRESULT STDMETHODCALLTYPE CLiveExdiGdbSrvServer::Ioctl( 
        /* [in] */ SAFEARRAY * pInputBuffer,
        /* [in] */ DWORD dwBuffOutSize,
        /* [out] */ SAFEARRAY * *pOutputBuffer)
{
    AsynchronousGdbSrvController * pController = GetGdbSrvController();
    if (pOutputBuffer == nullptr || pController == nullptr)
    {
        return E_POINTER;
    }

    HRESULT hr = E_INVALIDARG;
    VARTYPE dataType;
    if (FAILED(SafeArrayGetVartype(pInputBuffer, &dataType)) || dataType != VT_UI1)
    {
        return hr;
    }

    PVOID pRawBuffer = pInputBuffer->pvData;
    if (pRawBuffer == nullptr)
    {
        return hr;
    }

    try
    {
        ULONG bufferSize = pInputBuffer->rgsabound[0].cElements;
        const DBGENG_EXDI_IOCTL_CODE_V3_EX * pExdiV3 = reinterpret_cast<const DBGENG_EXDI_IOCTL_CODE_V3_EX *>(pRawBuffer);
        DBGENG_EXDI_IOCTL_CODE_V3_EX ioctlCode = *pExdiV3;
        switch(ioctlCode)
        {
            //  Get additional gdb server info that will be used by the debugger engine
            case DBGENG_EXDI_IOCTL_V3_GET_ADDITIONAL_SERVER_INFO:
            {
                if (bufferSize == sizeof(DBGENG_EXDI_IOCTL_V3_GET_ADDITIONAL_SERVER_INFO_EX_IN))
                {
                    const DBGENG_EXDI_IOCTL_V3_GET_ADDITIONAL_SERVER_INFO_EX_IN * pAdditionalInfo =
                        reinterpret_cast<const DBGENG_EXDI_IOCTL_V3_GET_ADDITIONAL_SERVER_INFO_EX_IN *>(pRawBuffer);
                    if (pAdditionalInfo -> request.HeuristicChunkSize)
                    {
                        size_t bytesToCopy = min(dwBuffOutSize, sizeof(m_heuristicChunkSize));
                        hr = SafeArrayFromByteArray(reinterpret_cast<const char *>(&m_heuristicChunkSize), bytesToCopy, pOutputBuffer);
                    }
                }
            }
            break;

            //  Store the KPCR value
            case DBGENG_EXDI_IOCTL_V3_STORE_KPCR_VALUE:
            {
                if (bufferSize == sizeof(DBGENG_EXDI_IOCTL_STORE_KPCR_V3_EX_IN))
                {
                    const DBGENG_EXDI_IOCTL_STORE_KPCR_V3_EX_IN * pKPCRV3 = reinterpret_cast<const DBGENG_EXDI_IOCTL_STORE_KPCR_V3_EX_IN *>(pRawBuffer);
                    //  Extract the processor number
                    ULONG processorNumber = pKPCRV3->processorNumber;
                    //  Extract the processor block array offset
                    ULONG64 kpcrOffset = pKPCRV3->kpcrOffset;
                    if (kpcrOffset != 0)
                    {
                        pController->SetKpcrOffset(processorNumber, kpcrOffset);
                        size_t bytesToCopy = min(dwBuffOutSize, sizeof(kpcrOffset));
                        hr = SafeArrayFromByteArray(reinterpret_cast<const char *>(&kpcrOffset), bytesToCopy, pOutputBuffer);
                    }
                }
            }
            break;

            //  This is not implemented by this COM server Exdi .
            case DBGENG_EXDI_IOCTL_V3_GET_NT_BASE_ADDRESS_VALUE:
            {
                hr = E_NOTIMPL;
            }
            break;

            //  Read the special registers content Architecture specific.
            case DBGENG_EXDI_IOCTL_V3_GET_SPECIAL_REGISTER_VALUE:
            {
                if (bufferSize == sizeof(DBGENG_EXDI_IOCTL_READ_SPECIAL_MEMORY_EX_IN))
                {
                    DBGENG_EXDI_IOCTL_READ_SPECIAL_MEMORY_EX_IN* const pSpecialRegs = reinterpret_cast<DBGENG_EXDI_IOCTL_READ_SPECIAL_MEMORY_EX_IN* const>(pRawBuffer);
                    memoryAccessType memoryType = { 0 };
                    memoryType.isSpecialRegs = 1;
                    SimpleCharBuffer buffer = pController->ReadSystemRegisters(pSpecialRegs->address, pSpecialRegs->bytesToRead, memoryType);
                    hr = SafeArrayFromByteArray(buffer.GetInternalBuffer(), buffer.GetLength(), pOutputBuffer);
                }
            }
            break;

            //  Read the special memory content Architecture specific.
            case DBGENG_EXDI_IOCTL_V3_GET_SUPERVISOR_MODE_MEM_VALUE:
            case DBGENG_EXDI_IOCTL_V3_GET_HYPERVISOR_MODE_MEM_VALUE:
            {
                if (bufferSize == sizeof(DBGENG_EXDI_IOCTL_READ_SPECIAL_MEMORY_EX_IN))
                {
                    DBGENG_EXDI_IOCTL_READ_SPECIAL_MEMORY_EX_IN * const pSpecialRegs = reinterpret_cast<DBGENG_EXDI_IOCTL_READ_SPECIAL_MEMORY_EX_IN * const>(pRawBuffer);
                    memoryAccessType memoryType = {0};
                    if (ioctlCode == DBGENG_EXDI_IOCTL_V3_GET_HYPERVISOR_MODE_MEM_VALUE)
                    {
                        memoryType.isHypervisor = 1;
                    }
                    else
                    {
                        memoryType.isSupervisor = 1;
                    }
                    SimpleCharBuffer buffer = pController->ReadMemory(pSpecialRegs->address, pSpecialRegs->bytesToRead, memoryType);
                    hr = SafeArrayFromByteArray(buffer.GetInternalBuffer(), buffer.GetLength(), pOutputBuffer);
                }
            }
            break;

            default:
            {
                hr = E_NOTIMPL;
            }
        }
        return hr;
    }
    CATCH_AND_RETURN_HRESULT;
}