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