📄 dbg.c
字号:
IN OUT PUSHORT pOutBufIndex,
IN USHORT nMaxBytes,
BOOL fIORead,
DWORD dwAddress,
DWORD dwSize,
DWORD dwData
)
{
DBGKD_COMMAND dbgkdCmdPacket;
STRING strIO;
dbgkdCmdPacket.u.ReadWriteIo.qwTgtIoAddress = dwAddress;
dbgkdCmdPacket.u.ReadWriteIo.dwDataSize = dwSize;
dbgkdCmdPacket.u.ReadWriteIo.dwDataValue = dwData;
strIO.Length = 0;
strIO.Buffer = 0;
strIO.MaximumLength = 0;
if (fIORead)
{
sprintf_temp (OutBuf, pOutBufIndex, &nMaxBytes, TEXT("IO Read: Address=0x%08X, Size=%u ==> "),dwAddress,dwSize);
KdpReadIoSpace (&dbgkdCmdPacket, &strIO, FALSE);
}
else
{
sprintf_temp (OutBuf, pOutBufIndex, &nMaxBytes, TEXT("IO Write: Address=0x%08X, Size=%u, Data=0x%08X ==> "),dwAddress,dwSize,dwData);
KdpWriteIoSpace (&dbgkdCmdPacket, &strIO, FALSE);
}
switch (dbgkdCmdPacket.dwReturnStatus)
{
case STATUS_SUCCESS:
if (fIORead)
{
sprintf_temp(OutBuf, pOutBufIndex, &nMaxBytes, TEXT("Success: Data=0x%08X\n"),dbgkdCmdPacket.u.ReadWriteIo.dwDataValue);
}
else
{
sprintf_temp(OutBuf, pOutBufIndex, &nMaxBytes, TEXT("Success\n"));
}
break;
case STATUS_ACCESS_VIOLATION:
sprintf_temp(OutBuf, pOutBufIndex, &nMaxBytes, TEXT("ERROR: Access Violation\n"));
break;
case STATUS_DATATYPE_MISALIGNMENT:
sprintf_temp(OutBuf, pOutBufIndex, &nMaxBytes, TEXT("ERROR: Datatype Misalignment\n"));
break;
case STATUS_INVALID_PARAMETER:
sprintf_temp(OutBuf, pOutBufIndex, &nMaxBytes, TEXT("ERROR: Invalid Parameter\n"));
break;
default:
sprintf_temp(OutBuf, pOutBufIndex, &nMaxBytes, TEXT("ERROR: Unknown Error\n"));
break;
}
// Include the NULL
(*pOutBufIndex)++;
return TRUE;
} // End of MarshalCriticalSectionInfo
/*++
Routine Name:
PrintHandleList
Routine Description:
Processes a handle request. This is called from the hl command in FlexPTI.
Formats a response in ASCII and stores in the buffer.
Arguments:
pszBuffer - [in] Pointer to buffer
cchBufLen - [in] Length of buffer
pHDD - [in] Pointer to handle description buffer
pHGD - [in] Pointer to handle data buffer
--*/
void PrintHandleList(LPSTR pszBuffer, UINT cchBufLen, PDBGKD_HANDLE_DESC_DATA pHDD, PDBGKD_HANDLE_GET_DATA pHGD)
{
// Some arbitrary format constants
const char pszFieldEndStr[] = " ";
const char pszLineEndStr[] = "\n";
const char pszBlockEndStr[] = "\n";
const UINT cchColWidth = 11;
// Compute some constants that make life easier
const PDBGKD_HANDLE_FIELD_DESC pFieldDesc = pHDD->out.pFieldDesc;
const PDBGKD_HANDLE_FIELD_DATA pFieldData = pHGD->out.pFields;
const LPSTR pszEndPtr = pszBuffer + cchBufLen - lengthof(pszBlockEndStr);
const UINT cFieldsPerLine = pHDD->out.cFields;
const UINT cFields = pHGD->out.cFields;
// This is the length of the "fixed" part of the line. The last field is
// allowed to be variable length and exceed the fixed column width of 11
// chars. This includes the line trailier, too.
const UINT cchFixedLineLen = ((cchColWidth + lengthof(pszFieldEndStr)) * (cFieldsPerLine - 1)) +
lengthof(pszLineEndStr);
// Some locals
NTSTATUS status = STATUS_SUCCESS;
PDBGKD_HANDLE_FIELD_DATA pCurField;
LPSTR pszLineStart;
UINT i, j, cchLen, cHandles;
// Defensive programming
if (cFieldsPerLine == 0)
{
DEBUGGERMSG(KDZONE_HANDLEEX, (L" ERROR: 0 fields per line!\r\n"));
status = STATUS_INTERNAL_ERROR;
goto Error;
}
// Defensive programming
if ((cFields % cFieldsPerLine) != 0)
{
DEBUGGERMSG(KDZONE_HANDLEEX, (L" ERROR: Query returned odd number of fields (%u fields total, %u fields/handle)\r\n", cFields, cFieldsPerLine));
status = STATUS_INTERNAL_ERROR;
goto Error;
}
cHandles = cFields / cFieldsPerLine;
DEBUGGERMSG(KDZONE_HANDLEEX, (L" Printing handle data: %u fields, %u handles\r\n", cFieldsPerLine, cHandles));
// Special case when we print no handles. We want the output to look nice,
// so skip headers and print the message.
if (cHandles == 0)
{
const char pszNoHandles[] = "No handles matched your query.";
if (cchBufLen < (lengthof(pszNoHandles) - 1))
{
status = STATUS_BUFFER_TOO_SMALL;
goto Error;
}
memcpy(pszBuffer, pszNoHandles, sizeof(pszNoHandles) - 1);
pszBuffer += (lengthof(pszNoHandles) - 1);
goto Done;
}
// Length of headers
i = cchFixedLineLen +
strlen(g_apszHandleFields[pFieldDesc[cFieldsPerLine - 1].nFieldId]);
// Do we have enough buffer space for headers?
if ((UINT)(pszEndPtr - pszBuffer) < i)
{
DEBUGGERMSG(KDZONE_HANDLEEX, (L" Buffer too small: need %u bytes, have %u bytes\r\n", i + 2, pszEndPtr - pszBuffer));
status = STATUS_BUFFER_TOO_SMALL;
goto Error;
}
// Write out headers
for(i = 0, pszLineStart = pszBuffer; i < cFieldsPerLine; i++)
{
const LPCSTR pszFieldName = g_apszHandleFields[pFieldDesc[i].nFieldId];
cchLen = strlen(pszFieldName);
memcpy(pszBuffer, pszFieldName, cchLen);
pszBuffer += cchLen;
if (i < (cFieldsPerLine - 1))
{
// Defensive programming
if (cchLen > cchColWidth)
{
DEBUGGERMSG(KDZONE_HANDLEEX, (L" Description for field ID %u is too long! (%u chars, %u max)\r\n", pFieldDesc[i].nFieldId, cchLen, cchColWidth));
status = STATUS_INTERNAL_ERROR;
goto Error;
}
if (cchLen < cchColWidth)
{
memset(pszBuffer, ' ', cchColWidth - cchLen);
pszBuffer += (cchColWidth - cchLen);
}
memcpy(pszBuffer, pszFieldEndStr, sizeof(pszFieldEndStr) - 1);
pszBuffer += (lengthof(pszFieldEndStr) - 1);
}
}
memcpy(pszBuffer, pszLineEndStr, sizeof(pszLineEndStr) - 1);
pszBuffer += (lengthof(pszLineEndStr) - 1);
pCurField = pFieldData;
// Each line has 1 handle on it
for(i = 0, pszLineStart = pszBuffer; i < cHandles; i++, pszLineStart = pszBuffer)
{
if ((UINT)(pszEndPtr - pszBuffer) < cchFixedLineLen)
break;
for(j = 0; j < cFieldsPerLine; j++, pCurField++)
{
cchLen = 0;
if (pCurField->fValid)
{
switch(pFieldDesc[j].nType)
{
case KD_FIELD_UINT:
cchLen = snprintf(pszBuffer, (UINT)(pszEndPtr - pszBuffer),
L"%u", pCurField->nData);
break;
case KD_FIELD_SINT:
cchLen = snprintf(pszBuffer, (UINT)(pszEndPtr - pszBuffer),
L"%i", pCurField->nData);
break;
case KD_FIELD_CHAR:
cchLen = snprintf(pszBuffer, (UINT)(pszEndPtr - pszBuffer),
L"%c", (WCHAR) pCurField->nData);
break;
case KD_FIELD_WCHAR:
cchLen = snprintf(pszBuffer, (UINT)(pszEndPtr - pszBuffer),
L"%c", pCurField->nData);
break;
case KD_FIELD_CHAR_STR:
cchLen = snprintf(pszBuffer, (UINT)(pszEndPtr - pszBuffer),
L"%a", pCurField->nData);
break;
case KD_FIELD_WCHAR_STR:
cchLen = snprintf(pszBuffer, (UINT)(pszEndPtr - pszBuffer),
L"%s", pCurField->nData);
break;
case KD_FIELD_PTR:
cchLen = snprintf(pszBuffer, (UINT)(pszEndPtr - pszBuffer),
L"%08p", pCurField->nData);
break;
case KD_FIELD_BOOL:
cchLen = snprintf(pszBuffer, (UINT)(pszEndPtr - pszBuffer),
L"%s", (pCurField->nData == 0 ? L"False" : L"True"));
break;
case KD_FIELD_HANDLE:
cchLen = snprintf(pszBuffer, (UINT)(pszEndPtr - pszBuffer),
L"%08p", pCurField->nData);
break;
case KD_FIELD_BITS:
cchLen = snprintf(pszBuffer, (UINT)(pszEndPtr - pszBuffer),
L"%08lX", pCurField->nData);
break;
default:
DEBUGGERMSG(KDZONE_HANDLEEX, (L" Invalid type ID %u\r\n", pFieldDesc[j].nType));
status = STATUS_INTERNAL_ERROR;
goto Error;
}
}
// Pad out to full width and insert trailing spaces if not on the
// last column.
if (j < (cFieldsPerLine - 1))
{
// On long fields, terminate with "..." to let the user know there
// was more data.
if (cchLen > cchColWidth)
{
pszBuffer[cchColWidth - 3] = '.';
pszBuffer[cchColWidth - 2] = '.';
pszBuffer[cchColWidth - 1] = '.';
}
else if (cchLen < cchColWidth)
{
memset(pszBuffer + cchLen, ' ', cchColWidth - cchLen);
}
pszBuffer += cchColWidth;
memcpy(pszBuffer, pszFieldEndStr, sizeof(pszFieldEndStr) - 1);
pszBuffer += (lengthof(pszFieldEndStr) - 1);
}
}
if (cchLen == -1)
break;
pszBuffer += cchLen;
if ((UINT)(pszEndPtr - pszBuffer) < (lengthof(pszLineEndStr) - 1))
break;
memcpy(pszBuffer, pszLineEndStr, sizeof(pszLineEndStr) - 1);
pszBuffer += (lengthof(pszLineEndStr) - 1);
}
// Back up to the previous line. If we completed successfully, then
// pszBuffer == pszLineStart and the pointer isn't moved.
pszBuffer = pszLineStart;
// Did we actually get any lines into the buffer?
if (i < 1)
{
status = STATUS_BUFFER_TOO_SMALL;
goto Error;
}
// Try to tell the user there's more data. It sucks that they can't
// really do anything about it.
if (i < cHandles)
{
const char szMoreString[] = "[More]\n";
if ((UINT)(pszEndPtr - pszBuffer) >= (lengthof(szMoreString) - 1))
{
memcpy(pszBuffer, szMoreString, sizeof(szMoreString) - 1);
pszBuffer += (lengthof(szMoreString) - 1);
}
}
// Append trailer
Done:
strcpy(pszBuffer, pszBlockEndStr);
return;
Error:
// Backtrack. Note that pszEndPtr already had the block suffix subtracted,
// so we have to add this back in.
pszBuffer = pszEndPtr - cchBufLen + lengthof(pszBlockEndStr);
// Append error message
i = 0;
AppendErrorToOutBuf_M(pszBuffer, status, i, cchBufLen);
}
// Buffers used in MarshalHandleQuery. The rest of the code will automatically
// pick up changes to these buffers.
char rgDummyDesc[sizeof(DBGKD_HANDLE_DESC_DATA) + (sizeof(DBGKD_HANDLE_FIELD_DESC) * 16)];
char rgDummyData[sizeof(DBGKD_HANDLE_GET_DATA) + (sizeof(DBGKD_HANDLE_FIELD_DATA) * 128)];
/*++
Routine Name:
MarshalHandleQuery
Routine Description:
Processes a handle request. This is called from the hl command in FlexPTI.
Null-terminated text for the end user is stored in the buffer.
Arguments:
pszBuffer - [in] Pointer to buffer
cBufLen - [in] Length of buffer
pszParams - [in] Pointer to first parameter
cParams - [in] Number of parameters
Return Value:
On success: TRUE
On error: FALSE, no additional information is available
--*/
static BOOL MarshalHandleQuery(LPSTR pszBuffer, UINT cBufLen, LPCSTR pszParams, UINT cParams)
{
const LPSTR pszEndPtr = pszBuffer + cBufLen;
NTSTATUS status;
UINT i;
DEBUGGERMSG(KDZONE_HANDLEEX, (L"++MarshalHandleQuery\r\n"));
if (cParams >= 1 && !strcmp(pszParams, "query"))
{
// "hl query [P:pid] [T:type]" - List handles matching filter
const PDBGKD_HANDLE_DESC_DATA pHDD = (PDBGKD_HANDLE_DESC_DATA) rgDummyDesc;
const PDBGKD_HANDLE_GET_DATA pHGD = (PDBGKD_HANDLE_GET_DATA) rgDummyData;
UINT32 nPIDMask = 0;
UINT32 nAPIMask = 0;
cParams--;
while(cParams > 0)
{
pszParams = GetNextParam(pszParams);
cParams--;
if (pszParams[0] == 'p' && pszParams[1] == ':')
{
i = strtoul(pszParams + 2, NULL, 10);
if (i >= MAX_PROCESSES || kdProcArray[i].dwVMBase == 0)
{
status = STATUS_INVALID_PARAMETER;
goto Error;
}
nPIDMask |= (1 << i);
}
else if (pszParams[0] == 't' && pszParams[1] == ':')
{
i = strtoul(pszParams + 2, NULL, 10);
if (i >= 32)
{
status = STATUS_INVALID_PARAMETER;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -