windows-nt/Source/XPSP1/NT/net/rras/ndis/ndproxy/kdext/dsocode.c
2020-09-26 16:20:57 +08:00

403 lines
11 KiB
C

/****************************** Module Header ******************************\
* Module Name: dsocode.c
*
* Copyright (c) 1985-96, Microsoft Corporation
*
* This file contains the dump structure offset (dso) extension. It is
* included by $(ALT_PROJECT)\dsotable.c which is generated by structo.exe
*
* History:
* 06/17/96 GerardoB Created
\***************************************************************************/
#include <stdexts.h>
/***************************************************************************\
* dsoTerminateString
*
* This is used to "parse" the command line. It null-terminates a space
* delimited string, returns its size and a pointer to the begining
* of next string
*
* 06/17/96 Created Gerardob
\***************************************************************************/
LPSTR dsoTerminateString(LPSTR psz, PDWORD pdwSize)
{
LPSTR pszWork = psz;
while (*pszWork != 0) {
if (*pszWork == ' ') {
*pszWork++ = 0;
break;
}
pszWork++;
}
*pdwSize = (DWORD)(pszWork - psz);
if (*pszWork != 0) {
(*pdwSize)--;
}
while ((*pszWork != 0) && (*pszWork == ' ')) {
pszWork++;
}
return pszWork;
}
/***************************************************************************\
* dsoGetOffset
*
* If the highest order bit of psot->dwOffset is set, then the value is a
* relative offset from the previous field; otherwise, it is the
* actual field offset from the beginnig of the structure
*
* 06/20/96 Created Gerardob
\***************************************************************************/
UINT dsoGetOffset (PSTRUCTUREOFFSETSTABLE psot)
{
if (!(psot->dwOffset & 0x80000000)) {
return psot->dwOffset;
} else {
return ((psot->dwOffset & ~0x80000000) + dsoGetOffset(psot - 1));
}
}
/***************************************************************************\
* dsoGetSize
*
* The field size is calculated by substracting its offset from the next
* field's offset. If the struct has unions, several "fields" might have
* the same offset, or a given table entry (i.e., a field) might have an
* offset value greater than the offset value for the next entry (a union
* of two structures).
*
* 06/26/96 Created Gerardob
\***************************************************************************/
UINT dsoGetSize (PSTRUCTUREOFFSETSTABLE psot, DWORD dwOffset)
{
DWORD dwNextFieldOffset;
do {
psot++;
dwNextFieldOffset = dsoGetOffset(psot);
} while (dwNextFieldOffset <= dwOffset);
return dwNextFieldOffset - dwOffset;
}
/***************************************************************************\
* dsoGetStruct
*
* 07/03/96 Created Gerardob
\***************************************************************************/
PSTRUCTURESTABLE dosGetStruct (LPSTR pszStruct, DWORD dwSize)
{
PSTRUCTURESTABLE pst = gst;
/*
* try an exact match
*/
while (pst->pszName != NULL) {
if (!_stricmp(pszStruct, pst->pszName)) {
return pst;
}
pst++;
}
/*
* Partial prefix match
*/
pst = gst;
while (pst->pszName != NULL) {
if (!_strnicmp(pszStruct, pst->pszName, dwSize)) {
return pst;
}
pst++;
}
return NULL;
}
/***************************************************************************\
* dsoGetField
*
* 07/03/96 Created Gerardob
\***************************************************************************/
PSTRUCTUREOFFSETSTABLE dosGetField (PSTRUCTUREOFFSETSTABLE psot, LPSTR pszField, DWORD dwSize)
{
PSTRUCTUREOFFSETSTABLE psotFirst = psot;
/*
* try an exact match
*/
while (psot->pszField != NULL) {
if (!_stricmp(pszField, psot->pszField)) {
return psot;
}
psot++;
}
/*
* Partial prefix match
*/
psot = psotFirst;
while (psot->pszField != NULL) {
if (!_strnicmp(pszField, psot->pszField, dwSize)) {
return psot;
}
psot++;
}
return NULL;
}
/***************************************************************************\
* Idso
*
* !dso StructName [FieldName] [Address]
*
* 06/17/96 Created Gerardob
\***************************************************************************/
BOOL Idso(DWORD opts, LPSTR pszCmdLine)
{
BOOL fOneField = FALSE;
DWORD dwOptions;
DWORD dwValue, dwSize, dwBytesRead, dwOffset, dwOffsetNext, dwFieldsPerRow, dwMoveSize;
DWORD dwBuffer [20]; /* Make sure it has an even number of elemnts and at least 4*/
const DWORD *pcdwLimit = dwBuffer + (sizeof(dwBuffer) / sizeof(*dwBuffer));
DWORD *pdwValue;
LPSTR pszField, pszAddress;
PBYTE pBufferOffset;
PSTRUCTURESTABLE pst;
PSTRUCTUREOFFSETSTABLE psot;
PVOID pAddress = NULL;
if (pszCmdLine == NULL) {
return FALSE;
}
/*
* NULL terminate first argument and get a pointer to
* second one (presumably the field name)
*/
/*
* Get the options, if any
*/
if (*pszCmdLine == '-') {
dwOptions = GetOpts(&pszCmdLine, NULL);
}
/*
* Find the struct table
*/
pszField = dsoTerminateString(pszCmdLine, &dwSize);
pst = dosGetStruct (pszCmdLine, dwSize);
if (pst == NULL) {
Print("Structure not found: %s\n", pszCmdLine);
return TRUE;
}
/*
* Got a table
*/
psot = pst->psot;
/*
* If there is another argument, let's assume a field name follows
*/
if (*pszField != 0) {
/*
* Find the field
*/
pszAddress = dsoTerminateString(pszField, &dwSize);
psot = dosGetField (psot, pszField, dwSize);
/*
* If it didn't find the field and an address was provided, game over.
* Otherwise, the second parameter might be the address
*/
if (psot == NULL) {
if (*pszAddress != 0) {
Print("Field not found: %s. Struct: %s\n", pszField, pst->pszName);
return TRUE;
} else {
pszAddress = pszField;
/*
* Reset psot since this argument was not a field
*/
psot = pst->psot;
}
} else {
fOneField = TRUE;
}
/*
* Get the pointer to the struct
*/
if (*pszAddress != 0) {
pAddress = EvalExp(pszAddress);
if (pAddress == NULL) {
/*
* EvalExp displayed the error message, so return silently
*/
return TRUE;
}
}
} /* if (*pszField != 0) */
/*
* If a field name was specified, dump that field only
* Otherwise, dump the whole table.
*/
if (fOneField) {
/*
* If no address available, just display the field name and offset
*/
dwOffset = dsoGetOffset(psot);
Print ("Structure %s - Size: %#lx\n", pst->pszName, pst->dwSize);
Print("Field: %s - Offset: %#lx\n", psot->pszField, dwOffset);
if (pAddress == NULL) {
return TRUE;
}
/*
* Printing field value
*/
/*123456789 1*/
Print("Address Value\n");
dwBytesRead = 0;
dwSize = dsoGetSize(psot, dwOffset);
/*
* Print 4 DWORDS per row; one row per loop
*/
do { /* while ((int)dwSize > 0) */
/*
* Read values for next row
*/
if (4 * sizeof(DWORD) >= dwSize) {
dwMoveSize = dwSize;
} else {
dwMoveSize = 4 * sizeof(DWORD);
}
moveBlock(dwBuffer, (PBYTE)pAddress + dwOffset + dwBytesRead, dwMoveSize);
pBufferOffset = (PBYTE)dwBuffer;
/*
* Print the address
*/
Print("%08lx ", (DWORD)((PBYTE)pAddress + dwOffset + dwBytesRead));
/*
* Keep track of bytes read (dwBytesRead) and bytes
* remaining to be read (dwSize)
*/
dwBytesRead += dwMoveSize;
dwSize -= dwMoveSize;
/*
* Print the values, one dword at the time
*/
while (dwMoveSize >= sizeof(DWORD)) {
Print("%08lx ", *((DWORD *)pBufferOffset));
pBufferOffset += sizeof(DWORD);
dwMoveSize -= sizeof(DWORD);
}
/*
* If less than a DWORD left, zero extend and print a DWORD
*/
if (dwMoveSize > 0) {
dwValue = 0;
memcpy(&dwValue, pBufferOffset, dwMoveSize);
Print("%0*lx", dwMoveSize * 2, dwValue);
}
Print("\n");
} while ((int)dwSize > 0);
return TRUE;
} /* if (fOneField) */
/*
* Printing all the fields.
*/
Print ("Structure %s - Size: %#lx\n", pst->pszName, pst->dwSize);
dwOffset = 0;
pBufferOffset = NULL; /* Forces the local buffer to be loaded */
dwFieldsPerRow = 0;
/*
* Loop through all fields in the table. Print one field per loop
*/
while (psot->pszField != NULL) {
/*
* Print two fields per row
*/
if (dwFieldsPerRow == 2) {
Print("\n");
dwFieldsPerRow = 1;
} else {
dwFieldsPerRow++;
}
/*
* If no address provided, Print field name(s) and offset(s) only
*/
if (pAddress == NULL) {
Print("%03lx %-34.33s", dsoGetOffset(psot), psot->pszField);
} else {
/*
* Printing offsets and values.
*
* Get the size of the value and max it to one DWORD
*/
dwOffsetNext = dsoGetOffset(psot + 1);
if (dwOffsetNext > dwOffset) {
dwSize = dwOffsetNext - dwOffset;
} else {
dwSize = dsoGetSize(psot, dwOffset);
}
if (dwSize > sizeof(DWORD)) {
dwSize = sizeof(DWORD);
}
/*
* Get a pointer to the value in the local buffer
* If the value is not in the buffer, load it
*/
pdwValue = (PDWORD)(pBufferOffset + dwOffset);
if ((pdwValue < dwBuffer) || (pdwValue + dwSize > pcdwLimit)) {
pBufferOffset = (PBYTE)dwBuffer - dwOffset;
pdwValue = dwBuffer;
if (sizeof(dwBuffer) >= pst->dwSize - dwOffset) {
dwMoveSize = pst->dwSize - dwOffset;
} else {
dwMoveSize = sizeof(dwBuffer);
}
moveBlock((PBYTE)dwBuffer, (PBYTE)pAddress + dwOffset, dwMoveSize);
}
/*
* Copy the value and print it
*/
dwValue = 0; /* in case size < sizeof(DWORD) */
memcpy(&dwValue, pdwValue, dwSize);
Print("(%03lx) %08lx %-24.23s", dwOffset, dwValue, psot->pszField);
} /* if (pAddress == NULL) */
dwOffset = dwOffsetNext;
psot++;
} /* while (psot->pszField != NULL) */
Print("\n");
return TRUE;
}