windows-nt/Source/XPSP1/NT/net/tcpip/driver/kdext2/ntkd/utils.c
2020-09-26 16:20:57 +08:00

581 lines
10 KiB
C

/*++
Copyright (c) 1999-2000 Microsoft Corporation
Module Name:
utils.c
Abstract:
Contains utilities for kd ext and parsing.
Author:
Scott Holden (sholden) 24-Apr-1999
Revision History:
--*/
#include "tcpipxp.h"
#include "tcpipkd.h"
PTCPIP_SRCH
ParseSrch(
PCSTR args,
ULONG ulDefaultOp,
ULONG ulAllowedOps
)
{
PTCPIP_SRCH pSrch = NULL;
char *pszArgs = NULL;
char *pszSrch;
ULONG cbArgs;
ULONG Status = STATUS_SUCCESS;
//
// Make a copy of the argument string to parse with.
//
cbArgs = strlen(args);
pszArgs = LocalAlloc(LPTR, cbArgs + 1);
if (pszArgs == NULL)
{
Status = STATUS_NO_MEMORY;
goto done;
}
strcpy(pszArgs, args);
//
// Allocate the return srch. Set default::assume default has no params.
//
pSrch = LocalAlloc(LPTR, sizeof(TCPIP_SRCH));
if (pSrch == NULL)
{
Status = STATUS_NO_MEMORY;
goto done;
}
pSrch->ulOp = ulDefaultOp;
// If we need to parse out an addr, do it first...
// Get first token in arg list.
pszSrch = mystrtok(pszArgs, " \t\n");
if (pszSrch == NULL)
{
// If default is invalid (i.e. NO default), return error.
if (pSrch->ulOp == 0 ||
(ulAllowedOps & TCPIP_SRCH_PTR_LIST))
{
Status = STATUS_INVALID_PARAMETER;
dprintf("xxx1\n");
}
goto done;
}
if (ulAllowedOps & TCPIP_SRCH_PTR_LIST)
{
pSrch->ListAddr = GetExpression(pszSrch);
pszSrch = mystrtok(NULL, " \t\n");
if (pszSrch == NULL)
{
if (pSrch->ulOp == 0)
{
Status = STATUS_INVALID_PARAMETER;
}
goto done;
}
}
if (strcmp(pszSrch, "all") == 0)
{
pSrch->ulOp = TCPIP_SRCH_ALL;
}
else if (strcmp(pszSrch, "ipaddr") == 0)
{
CHAR szIP[20];
CHAR *p;
ULONG i;
pSrch->ulOp = TCPIP_SRCH_IPADDR;
pSrch->ipaddr = 0;
pszSrch = mystrtok(NULL, " \t\n");
if (pszSrch == NULL || strlen(pszSrch) >= 15)
{
Status = STATUS_INVALID_PARAMETER;
goto done;
}
strcpy(szIP, pszSrch);
p = mystrtok(szIP, ".");
for (i = 0; i < 4; i++)
{
pSrch->ipaddr |= (atoi(p) << (i*8));
p = mystrtok(NULL, ".");
if (p == NULL)
{
break;
}
}
if (i != 3)
{
Status = STATUS_INVALID_PARAMETER;
goto done;
}
}
else if (strcmp(pszSrch, "port") == 0)
{
pSrch->ulOp = TCPIP_SRCH_PORT;
pszSrch = mystrtok(NULL, " \t\n");
if (pszSrch == NULL)
{
Status = STATUS_INVALID_PARAMETER;
goto done;
}
pSrch->port = (USHORT)atoi(pszSrch);
}
else if (strcmp(pszSrch, "prot") == 0)
{
pSrch->ulOp = TCPIP_SRCH_PROT;
pszSrch = mystrtok(NULL, " \t\n");
if (pszSrch == NULL)
{
Status = STATUS_INVALID_PARAMETER;
goto done;
}
if (strcmp(pszSrch, "raw") == 0)
{
pSrch->prot = PROTOCOL_RAW;
}
else if (strcmp(pszSrch, "udp") == 0)
{
pSrch->prot = PROTOCOL_UDP;
}
else if (strcmp(pszSrch, "tcp") == 0)
{
pSrch->prot = PROTOCOL_TCP;
}
else
{
Status = STATUS_INVALID_PARAMETER;
goto done;
}
}
else if (strcmp(pszSrch, "context") == 0)
{
pSrch->ulOp = TCPIP_SRCH_CONTEXT;
pszSrch = mystrtok(NULL, " \t\n");
if (pszSrch == NULL)
{
Status = STATUS_INVALID_PARAMETER;
goto done;
}
pSrch->context = atoi(pszSrch);
}
else if (strcmp(pszSrch, "stats") == 0)
{
pSrch->ulOp = TCPIP_SRCH_STATS;
}
else
{
// Invalid srch request. Fail.
Status = STATUS_INVALID_PARAMETER;
goto done;
}
// Now see if this is an expected type!!!
if ((pSrch->ulOp & ulAllowedOps) == 0)
{
dprintf("invalid operation for current srch" ENDL);
Status = STATUS_INVALID_PARAMETER;
goto done;
}
done:
if (pszArgs)
{
LocalFree(pszArgs);
}
if (Status != STATUS_SUCCESS)
{
if (pSrch)
{
LocalFree(pSrch);
pSrch = NULL;
}
}
return (pSrch);
}
char *mystrtok ( char *string, char * control )
{
static unsigned char *str;
char *p, *s;
if( string )
str = string;
if( str == NULL || *str == '\0' )
return NULL;
//
// Skip leading delimiters...
//
for( ; *str; str++ ) {
for( s=control; *s; s++ ) {
if( *str == *s )
break;
}
if( *s == '\0' )
break;
}
//
// Was it was all delimiters?
//
if( *str == '\0' ) {
str = NULL;
return NULL;
}
//
// We've got a string, terminate it at first delimeter
//
for( p = str+1; *p; p++ ) {
for( s = control; *s; s++ ) {
if( *p == *s ) {
s = str;
*p = '\0';
str = p+1;
return s;
}
}
}
//
// We've got a string that ends with the NULL
//
s = str;
str = NULL;
return s;
}
ULONG
GetUlongValue (
PCHAR String
)
{
ULONG Location;
ULONG Value;
ULONG result;
Location = GetExpression( String );
if (!Location) {
dprintf("unable to get %s\n",String);
return 0;
}
if ((!ReadMemory((DWORD)Location,&Value,sizeof(ULONG),&result)) ||
(result < sizeof(ULONG))) {
dprintf("unable to get %s\n",String);
return 0;
}
return Value;
}
BOOL
GetData(
PVOID pvData,
ULONG cbData,
ULONG_PTR Address,
PCSTR pszDataType
)
{
BOOL b;
ULONG cbRead;
ULONG count = cbData;
while(cbData > 0)
{
if (count >= 3000)
count = 3000;
b = ReadMemory(Address, pvData, count, &cbRead );
if (!b || cbRead != count )
{
dprintf( "Unable to read %u bytes at %X, for %s\n", cbData, Address, pszDataType );
return (FALSE);
}
Address += count;
cbData -= count;
pvData = (PVOID)((ULONG_PTR)pvData + count);
// if (CheckControlC())
// {
// dprintf("ctrl-c\n");
// return (FALSE);
// }
}
return (TRUE);
}
BOOL
KDDump_ULONG(
PCHAR pVar,
PCHAR pName
)
{
ULONG_PTR Addr;
ULONG Value;
BOOL fStatus;
Addr = GetExpression(pVar);
if (Addr == 0)
{
dprintf("Failed to get %s" ENDL, pVar);
return (FALSE);
}
fStatus = GetData(&Value, sizeof(Value), Addr, "ULONG");
if (fStatus == FALSE)
{
dprintf("Failed to read %s @ %x" ENDL, pVar, Addr);
return (FALSE);
}
PrintFieldName(pName);
dprintf("%-10u", Value);
return (TRUE);
}
BOOL
KDDump_LONG(
PCHAR pVar,
PCHAR pName
)
{
ULONG_PTR Addr;
LONG Value;
BOOL fStatus;
Addr = GetExpression(pVar);
if (Addr == 0)
{
dprintf("Failed to get %s" ENDL, pVar);
return (FALSE);
}
fStatus = GetData(&Value, sizeof(Value), Addr, "LONG");
if (fStatus == FALSE)
{
dprintf("Failed to read %s @ %x" ENDL, pVar, Addr);
return (FALSE);
}
PrintFieldName(pName);
dprintf("%-10d", Value);
return (TRUE);
}
BOOL
KDDump_BOOLEAN(
PCHAR pVar,
PCHAR pName
)
{
ULONG_PTR Addr;
BOOLEAN Value;
BOOL fStatus;
Addr = GetExpression(pVar);
if (Addr == 0)
{
dprintf("Failed to get %s" ENDL, pVar);
return (FALSE);
}
fStatus = GetData(&Value, sizeof(Value), Addr, "BOOLEAN");
if (fStatus == FALSE)
{
dprintf("Failed to read %s @ %x" ENDL, pVar, Addr);
return (FALSE);
}
PrintFieldName(pName);
dprintf("%-10s", Value == TRUE ? "TRUE" : "FALSE");
return (TRUE);
}
BOOL
KDDump_uchar(
PCHAR pVar,
PCHAR pName
)
{
ULONG_PTR Addr;
uchar Value;
BOOL fStatus;
Addr = GetExpression(pVar);
if (Addr == 0)
{
dprintf("Failed to get %s" ENDL, pVar);
return (FALSE);
}
fStatus = GetData(&Value, sizeof(Value), Addr, "uchar");
if (fStatus == FALSE)
{
dprintf("Failed to read %s @ %x" ENDL, pVar, Addr);
return (FALSE);
}
PrintFieldName(pName);
dprintf("%-10u", Value);
return (TRUE);
}
BOOL
KDDump_ushort(
PCHAR pVar,
PCHAR pName
)
{
ULONG_PTR Addr;
ushort Value;
BOOL fStatus;
Addr = GetExpression(pVar);
if (Addr == 0)
{
dprintf("Failed to get %s" ENDL, pVar);
return (FALSE);
}
fStatus = GetData(&Value, sizeof(Value), Addr, "ushort");
if (fStatus == FALSE)
{
dprintf("Failed to read %s @ %x" ENDL, pVar, Addr);
return (FALSE);
}
PrintFieldName(pName);
dprintf("%-10hu", Value);
return (TRUE);
}
BOOL
KDDump_PtrSymbol(
PCHAR pVar,
PCHAR pName
)
{
ULONG_PTR Addr;
ULONG_PTR Value;
BOOL fStatus;
Addr = GetExpression(pVar);
if (Addr == 0)
{
dprintf("Failed to get %s" ENDL, pVar);
return (FALSE);
}
fStatus = GetData(&Value, sizeof(Value), Addr, "ULONG_PTR");
if (fStatus == FALSE)
{
dprintf("Failed to read %s @ %x" ENDL, pVar, Addr);
return (FALSE);
}
PrintFieldName(pName);
DumpPtrSymbol((PVOID) Value);
return (TRUE);
}
BOOL
KDDump_Queue(
PCHAR pVar,
PCHAR pName
)
{
ULONG_PTR Addr;
Queue Value;
BOOL fStatus;
Addr = GetExpression(pVar);
if (Addr == 0)
{
dprintf("Failed to get %s" ENDL, pVar);
return (FALSE);
}
fStatus = GetData(&Value, sizeof(Value), Addr, "Queue");
if (fStatus == FALSE)
{
dprintf("Failed to read %s @ %x" ENDL, pVar, Addr);
return (FALSE);
}
PrintFieldName(pName);
dprintf("q_next = %-10lx", Value.q_next);
dprintf("q_prev = %-10lx", Value.q_prev);
dprintf("%s", (Value.q_next == (Queue *)Addr) ? "[Empty]" : "");
return (TRUE);
}