windows-nt/Source/XPSP1/NT/net/qos/pclass/kdext/kdgpc.c
2020-09-26 16:20:57 +08:00

1095 lines
26 KiB
C

#include "precomp.h"
//
// The ExtensionApis is a mandatory global variable, which should
// have this exact name. All definitions of callbacks to the windbg
// are using this variable.
//
WINDBG_EXTENSION_APIS ExtensionApis;
USHORT g_MajorVersion;
USHORT g_MinorVersion;
//
// Prototypes
//
VOID
PrintCf(
PCF_BLOCK pCf
);
VOID
PrintClient(
PCLIENT_BLOCK pClient
);
VOID
PrintBlob(
PBLOB_BLOCK pBlob
);
VOID
PrintPattern(
PPATTERN_BLOCK pPattern
);
VOID
PrintStat(
PGPC_STAT pStat
);
BOOL
GetDwordExpr(
char* expr,
DWORD* pdwAddress,
DWORD* pValue
);
//
// API's
//
LPEXT_API_VERSION
ExtensionApiVersion(
void
)
/*++
Function Description:
Windbg calls this function to match between the version of windbg and the
extension. If the versions doesn't match, windbg will not load the extension.
--*/
{
static EXT_API_VERSION ApiVersion =
{ 3, 5, EXT_API_VERSION_NUMBER, 0 };
return &ApiVersion;
}
void
WinDbgExtensionDllInit(
PWINDBG_EXTENSION_APIS lpExtensionApis,
USHORT MajorVersion,
USHORT MinorVersion
)
/*++
Function Description:
When windbg loads the extension, it first call this function. You can
perform various intialization here.
Arguments:
lpExtensionApis - A structure that contains the callbacks to functions that
I can use to do standard operation. I must store this in a global
variable called 'ExtensionApis'.
MajorVersion - Indicates if target machine is running checked build or free.
0x0C - Checked build.
0x0F - Free build.
MinorVersion - The Windows NT build number (for example, 1381 for NT4).
--*/
{
ExtensionApis = *lpExtensionApis;
g_MajorVersion = MajorVersion;
g_MinorVersion = MinorVersion;
}
DECLARE_API( version )
{
#if DBG
PCHAR DebuggerType = "Checked";
#else
PCHAR DebuggerType = "Free";
#endif
dprintf("KDGPC: %s Extension dll for Build %d debugging %s kernel for Build %d\n",
DebuggerType,
VER_PRODUCTBUILD,
g_MajorVersion == 0x0c ? "Checked" : "Free",
g_MinorVersion
);
}
VOID
CheckVersion(
VOID
)
/*++
Function Description:
This function is called before every command. It gives the extension
a chance to compare between the versions of the target and the extension.
In this demo, I don't do much with that.
--*/
{
#if DBG
if ((g_MajorVersion != 0x0c) || (g_MinorVersion != VER_PRODUCTBUILD)) {
dprintf("\r\n*** Extension DLL(%d Checked) does not match target system(%d %s)\r\n\r\n",
(VER_PRODUCTBUILD, g_MinorVersion, g_MajorVersion==0x0f) ? "Free" : "Checked" );
}
#else
// if ((g_MajorVersion != 0x0f) || (g_MinorVersion != VER_PRODUCTBUILD)) {
// dprintf("\r\n*** Extension DLL(%d Free) does not match target system(%d %s)\r\n\r\n",
// (VER_PRODUCTBUILD, g_MinorVersion, (g_MajorVersion==0x0f) ? "Free" : "Checked" );
// }
#endif
}
DECLARE_API( help )
/*++
Function Description:
This is the implementation of the '!help' extension command. It lists
all available command in this debugger extension.
--*/
{
dprintf(
"help - shows this list\n"
"cf - print the CF list\n"
"client [addr] - print the client block"
"blob [addr] - print the blob list for the QoS CF, or the specified blob\n"
"pattern [addr] - print the pattern block\n"
"stat - print the statistics"
);
}
DECLARE_API( cf )
/*++
Function Description:
This function prints all the CF in the list. If args is specified, only that CF
will be printed. Currently these are supported:
0 - for CF_QOS
--*/
{
DWORD TargetGlobalData;
GLOBAL_BLOCK LocalGlobalData;
PLIST_ENTRY pHead, pEntry;
DWORD TargetCf;
CF_BLOCK LocalCf;
ULONG result;
ULONG CfIndex = (-1);
char *lerr;
TargetGlobalData = GetExpression( "MSGPC!glData" );
if( !TargetGlobalData )
{
dprintf( "Can't find the address of 'glData'" );
return;
}
//
if ( !ReadMemory(
TargetGlobalData,
&LocalGlobalData,
sizeof(LocalGlobalData),
&result
)) {
dprintf( "Can't read memory from 0x%x", TargetGlobalData );
return;
}
//
//
//
if ( args )
CfIndex = strtol( args, &lerr, 10 );
pHead = (PLIST_ENTRY)((PUCHAR)TargetGlobalData + FIELD_OFFSET(GLOBAL_BLOCK, CfList));
pEntry = LocalGlobalData.CfList.Flink;
while ( pHead != pEntry ) {
TargetCf = (DWORD)CONTAINING_RECORD( pEntry, CF_BLOCK, Linkage );
if ( !ReadMemory( TargetCf,
&LocalCf,
sizeof(LocalCf),
&result ) ) {
dprintf( "Can't read memory from 0x%x", TargetCf );
} else if ( CfIndex == (-1) || LocalCf.AssignedIndex == CfIndex ) {
PrintCf( &LocalCf );
}
pEntry = LocalCf.Linkage.Flink;
}
}
DECLARE_API( blob )
/*++
Function Description:
This function prints all the blob in the QoS CF list.
If args is specified it is used as the blob addr.
--*/
{
DWORD TargetGlobalData;
GLOBAL_BLOCK LocalGlobalData;
PLIST_ENTRY pHead, pEntry;
DWORD TargetCf;
CF_BLOCK LocalCf;
ULONG result;
ULONG TargetBlob = 0;
BLOB_BLOCK LocalBlob;
char *lerr;
if ( args )
TargetBlob = GetExpression( args );
if (TargetBlob) {
if ( !ReadMemory( TargetBlob,
&LocalBlob,
sizeof(LocalBlob),
&result ) ) {
dprintf( "Can't read memory from 0x%x", TargetBlob );
} else {
PrintBlob( &LocalBlob );
}
return;
}
#if 0
//
// scan the blob list for the QoS CF
//
TargetGlobalData = GetExpression( "MSGPC!glData" );
if( !TargetGlobalData )
{
dprintf( "Can't find the address of 'glData'" );
return;
}
//
if ( !ReadMemory(
TargetGlobalData,
&LocalGlobalData,
sizeof(LocalGlobalData),
&result
)) {
dprintf( "Can't read memory from 0x%x", TargetGlobalData );
return;
}
//
//
//
pHead = (PLIST_ENTRY)((PUCHAR)TargetGlobalData + FIELD_OFFSET(GLOBAL_BLOCK, CfList));
pEntry = LocalGlobalData.CfList.Flink;
while ( pHead != pEntry ) {
TargetCf = (DWORD)CONTAINING_RECORD( pEntry, CF_BLOCK, Linkage );
if ( !ReadMemory( TargetCf,
&LocalCf,
sizeof(LocalCf),
&result ) ) {
dprintf( "Can't read memory from 0x%x", TargetCf );
} else if ( CfIndex == (-1) || LocalCf.AssignedIndex == CfIndex ) {
PrintCf( &LocalCf );
}
pEntry = LocalCf.Linkage.Flink;
}
#endif
}
DECLARE_API( client )
/*++
Function Description:
This function prints either the client addr or all the clients
--*/
{
DWORD TargetGlobalData;
GLOBAL_BLOCK LocalGlobalData;
PLIST_ENTRY pHead, pEntry;
PLIST_ENTRY pHead1, pEntry1;
DWORD TargetCf;
CF_BLOCK LocalCf;
ULONG result;
ULONG TargetClient = 0;
CLIENT_BLOCK LocalClient;
int i = 0;
if ( args )
TargetClient = GetExpression( args );
if (TargetClient) {
if ( !ReadMemory( TargetClient,
&LocalClient,
sizeof(LocalClient),
&result ) ) {
dprintf( "Can't read memory from 0x%x", TargetClient );
} else {
dprintf( "Client = 0x%X: ", TargetClient );
PrintClient( &LocalClient );
}
return;
}
//
// scan the client list for the QoS CF
//
TargetGlobalData = GetExpression( "MSGPC!glData" );
if( !TargetGlobalData )
{
dprintf( "Can't find the address of 'glData'" );
return;
}
//
if ( !ReadMemory(
TargetGlobalData,
&LocalGlobalData,
sizeof(LocalGlobalData),
&result
)) {
dprintf( "Can't read memory from 0x%x", TargetGlobalData );
return;
}
//
//
//
pHead = (PLIST_ENTRY)((PUCHAR)TargetGlobalData + FIELD_OFFSET(GLOBAL_BLOCK, CfList));
pEntry = LocalGlobalData.CfList.Flink;
while ( pHead != pEntry ) {
TargetCf = (DWORD)CONTAINING_RECORD( pEntry, CF_BLOCK, Linkage );
if ( !ReadMemory( TargetCf,
&LocalCf,
sizeof(LocalCf),
&result ) ) {
dprintf( "Can't read memory from 0x%x", TargetCf );
return;
} else {
dprintf( "\nClients for CF=%d\n", LocalCf.AssignedIndex );
pHead1 = (PLIST_ENTRY)((PUCHAR)TargetCf + FIELD_OFFSET(CF_BLOCK, ClientList));
pEntry1 = LocalCf.ClientList.Flink;
while ( pHead1 != pEntry1 ) {
TargetClient = (DWORD)CONTAINING_RECORD( pEntry1, CLIENT_BLOCK, ClientLinkage );
if ( !ReadMemory( TargetClient,
&LocalClient,
sizeof(LocalClient),
&result ) ) {
dprintf( "Can't read memory from 0x%x", TargetClient );
return;
} else {
dprintf( "Client [%d] = 0x%X: ", i++, TargetClient );
PrintClient( &LocalClient );
}
pEntry1 = LocalClient.ClientLinkage.Flink;
}
}
pEntry = LocalCf.Linkage.Flink;
}
}
BOOL
GetDwordExpr(
char* expr,
DWORD* pdwAddress,
DWORD* pValue
)
/*++
Function Description:
This function gets as an argument a string which represent a DWORD
variable. The funciton finds its address (if the symbols are loaded),
and then grab the dword value from that address.
Arguments:
expr [in] - A null terminated string, represent the variable.
pdwAddress [out, optional] - Optinally return the address of the variable.
pValue [out] - returns the value of the DWORD variable.
Return Value:
true/false, if the function succeeded or failed.
--*/
{
ULONG result;
DWORD dwAddress;
if( pdwAddress )
*pdwAddress = 0;
*pValue = 0;
dwAddress = GetExpression( expr );
if( !dwAddress )
return FALSE;
if( !ReadMemory( dwAddress, pValue, sizeof(DWORD), &result ) )
return FALSE;
if( pdwAddress )
*pdwAddress = dwAddress;
return TRUE;
}
VOID
PrintCf(
PCF_BLOCK pCf
)
/*++
Function Description:
This function gets as an argument a CF block pointer,
and does a pretty print.
Arguments:
pCf - pointer to CF block
Return Value:
none
--*/
{
int i;
dprintf( " Linkage = { 0x%X, 0x%X }\n", pCf->Linkage.Flink, pCf->Linkage.Blink );
dprintf( " ClientList = { 0x%X, 0x%X }\n",
pCf->ClientList.Flink,
pCf->ClientList.Blink );
dprintf( " BlobList = { 0x%X, 0x%X }\n",
pCf->BlobList.Flink,
pCf->BlobList.Blink );
dprintf( " NumberOfClients = %d\n", pCf->NumberOfClients );
dprintf( " AssignedIndex = 0x%x\n", pCf->AssignedIndex );
dprintf( " ClientIndexes = %d\n", pCf->ClientIndexes );
dprintf( " MaxPriorities = %d\n", pCf->MaxPriorities );
dprintf( " arpGenericDb = 0x%X\n", &pCf->arpGenericDb );
for ( i = GPC_PROTOCOL_TEMPLATE_IP; i < GPC_PROTOCOL_TEMPLATE_MAX; i++ ) {
dprintf( " [%d] = %d\n", i, (ULONG)pCf->arpGenericDb[i] );
}
}
VOID
PrintBlob(
PBLOB_BLOCK pBlob
)
/*++
Function Description:
This function gets as an argument a BLOB block pointer,
and does a pretty print.
Arguments:
pBlob - pointer to BLOB block
Return Value:
none
--*/
{
int i;
dprintf( " ObjectType = %d\n", pBlob->ObjectType );
dprintf( " ClientLinkage = { 0x%X, 0x%X }\n",
pBlob->ClientLinkage.Flink,
pBlob->ClientLinkage.Blink );
dprintf( " PatternList = { 0x%X, 0x%X }\n",
pBlob->PatternList.Flink,
pBlob->PatternList.Blink );
dprintf( " CfLinkage = { 0x%X, 0x%X }\n",
pBlob->CfLinkage.Flink,
pBlob->CfLinkage.Blink );
dprintf( " RefCount = %d\n", pBlob->RefCount );
dprintf( " State = 0x%x\n", pBlob->State );
dprintf( " arClientCtx[]:\n" );
for ( i = 0; i < MAX_CLIENTS_CTX_PER_BLOB; i++ ) {
dprintf( " [%d] = 0x%x\n", i, (ULONG)pBlob->arClientCtx[i] );
}
}
VOID
PrintClient(
PCLIENT_BLOCK pClient
)
/*++
Function Description:
This function gets as an argument a CLIENT block pointer,
and does a pretty print.
Arguments:
pClient - pointer to CLIENT block
Return Value:
none
--*/
{
DWORD TargetCf;
CF_BLOCK LocalCf;
ULONG result;
TargetCf = (DWORD)pClient->pCfBlock;
if ( !ReadMemory( TargetCf,
&LocalCf,
sizeof(LocalCf),
&result ) ) {
dprintf( "Can't read memory from 0x%x", TargetCf );
return;
}
if (pClient->Flags & GPC_FLAGS_USERMODE_CLIENT) {
dprintf( " User Mode Client\n" );
} else {
if (GetExpression( "PSCHED!AddCfInfoNotify" ) == (DWORD)pClient->FuncList.ClAddCfInfoNotifyHandler
&& (LocalCf.AssignedIndex == GPC_CF_QOS || LocalCf.AssignedIndex == GPC_CF_CLASS_MAP)) {
dprintf( " Probably PSCHED client\n" );
} else if (GetExpression( "TCPIP!GPCcfInfoAddNotify" ) == (DWORD)pClient->FuncList.ClAddCfInfoNotifyHandler
&& (LocalCf.AssignedIndex == GPC_CF_QOS || LocalCf.AssignedIndex == GPC_CF_IPSEC)) {
dprintf( " Probably TCPIP client\n" );
} else if (GetExpression( "ATMARPC!AtmArpGpcAddCfInfoComplete" ) == (DWORD)pClient->FuncList.ClAddCfInfoNotifyHandler
&& (LocalCf.AssignedIndex == GPC_CF_QOS)) {
dprintf( " Probably ATMARPC client\n" );
} else if (0 == (DWORD)pClient->FuncList.ClAddCfInfoNotifyHandler
&& (LocalCf.AssignedIndex == GPC_CF_IPSEC)) {
dprintf( " Probably IPSEC client\n" );
} else {
dprintf( " Unknown client\n" );
}
}
dprintf( " ObjectType = %d\n", pClient->ObjectType );
dprintf( " ClientLinkage = { 0x%X, 0x%X }\n",
pClient->ClientLinkage.Flink,
pClient->ClientLinkage.Blink );
dprintf( " BlobList = { 0x%X, 0x%X }\n",
pClient->BlobList.Flink,
pClient->BlobList.Blink );
dprintf( " Parrent CF = 0x%X\n", pClient->pCfBlock );
dprintf( " Client Ctx = 0x%X\n", pClient->ClientCtx );
dprintf( " AssignedIndex = %d\n", pClient->AssignedIndex );
dprintf( " Flags = 0x%X %s %s \n",
pClient->Flags,
(pClient->Flags & GPC_FLAGS_USERMODE_CLIENT)?"UserMode":"" ,
(pClient->Flags & GPC_FLAGS_FRAGMENT)?"Handle Fragments":""
);
dprintf( " State = %d\n", pClient->State );
dprintf( " RefCount = %d\n", pClient->RefCount );
dprintf( " File Object = 0x%X\n", pClient->pFileObject );
dprintf( " Client Handle = %d\n", pClient->ClHandle );
dprintf( " Client Handlers:\n" );
dprintf( " Add Notify = 0x%X\n", pClient->FuncList.ClAddCfInfoCompleteHandler );
dprintf( " Add Complete = 0x%X\n", pClient->FuncList.ClAddCfInfoNotifyHandler );
dprintf( " Modify Notify = 0x%X\n", pClient->FuncList.ClModifyCfInfoCompleteHandler );
dprintf( " Modify Complete = 0x%X\n", pClient->FuncList.ClModifyCfInfoNotifyHandler );
dprintf( " Remove Notify = 0x%X\n", pClient->FuncList.ClRemoveCfInfoCompleteHandler );
dprintf( " Remove Complete = 0x%X\n", pClient->FuncList.ClRemoveCfInfoNotifyHandler );
dprintf( " Get CfInfo Name = 0x%X\n", pClient->FuncList.ClGetCfInfoName );
}
VOID
PrintPattern(
PPATTERN_BLOCK pPattern
)
/*++
Function Description:
This function gets as an argument a PATTERN block pointer,
and does a pretty print.
Arguments:
pPattern - pointer to PATTERN block
Return Value:
none
--*/
{
int i;
dprintf( " ObjectType = %d\n", pPattern->ObjectType );
dprintf( " BlobLinkage[]:\n" );
for ( i = 0; i < GPC_CF_MAX; i++ ) {
dprintf( " [%d] = {0x%X,0x%X}\n", i,
pPattern->BlobLinkage[i].Flink,
pPattern->BlobLinkage[i].Blink
);
}
dprintf( " TimerLinkage = { 0x%X, 0x%X }\n",
pPattern->TimerLinkage.Flink,
pPattern->TimerLinkage.Blink );
dprintf( " Owner client = 0x%X\n", pPattern->pClientBlock );
dprintf( " Auto client = 0x%X\n", pPattern->pAutoClient );
dprintf( " Classification block = 0x%X\n", pPattern->pClassificationBlock );
dprintf( " Ref Count = %d\n", pPattern->RefCount );
dprintf( " Client Ref Count = %d\n", pPattern->ClientRefCount );
dprintf( " Flags = 0x%x %s %s \n", pPattern->Flags ,
(pPattern->Flags & PATTERN_SPECIFIC)?"Specific":"",
(pPattern->Flags & PATTERN_AUTO)?"Auto":""
);
dprintf( " Priority = %d\n", pPattern->Priority );
dprintf( " Client handle = 0x%x\n", pPattern->ClHandle );
dprintf( " Protocol = 0x%x\n", pPattern->ProtocolTemplate );
}
VOID
PrintStat(
PGPC_STAT pStat
)
/*++
Function Description:
Prints the GPC stat structure
Arguments:
pStat - pointer to GPC stat strucutre
Return Value:
none
--*/
{
PPROTOCOL_STAT pProtocol;
int i;
dprintf( "Created CF = %d\n", pStat->CreatedCf );
dprintf( "Deleted Cf = %d\n", pStat->DeletedCf );
dprintf( "Rejected Cf = %d\n", pStat->RejectedCf );
dprintf( "Current Cf = %d\n", pStat->CurrentCf );
dprintf( "Inserted HF= %d\n", pStat->InsertedHF );
dprintf( "Removed HF= %d\n", pStat->RemovedHF );
for( i = 0; i < GPC_CF_MAX; i++) {
dprintf( "CF[%d] info:\n", i);
dprintf( " Created Blobs = %d\n", pStat->CfStat[i].CreatedBlobs );
dprintf( " Modified Blobs = %d\n", pStat->CfStat[i].ModifiedBlobs );
dprintf( " Deleted Blobs = %d\n", pStat->CfStat[i].DeletedBlobs );
dprintf( " Rejected Blobs = %d\n", pStat->CfStat[i].RejectedBlobs );
dprintf( " Current Blobs = %d\n", pStat->CfStat[i].CurrentBlobs );
dprintf( " Deref Blobs to zero = %d\n", pStat->CfStat[i].DerefBlobs2Zero );
dprintf( "\n" );
}
pProtocol = &pStat->ProtocolStat[GPC_PROTOCOL_TEMPLATE_IP];
dprintf( "IP stats: Specific Patterns Generic Patterns Auto Patterns\n" );
dprintf( " Created = %8d %8d %8d\n",
pProtocol->CreatedSp, pProtocol->CreatedGp, pProtocol->CreatedAp );
dprintf( " Deleted = %8d %8d %8d\n",
pProtocol->DeletedSp, pProtocol->DeletedGp, pProtocol->DeletedAp );
dprintf( " Rejected = %8d %8d %8d\n",
pProtocol->RejectedSp, pProtocol->RejectedGp, pProtocol->RejectedAp );
dprintf( " Current = %8d %8d %8d\n",
pProtocol->CurrentSp, pProtocol->CurrentGp, pProtocol->CurrentAp );
dprintf( "\n" );
dprintf( " Classification Requests = %d\n", pProtocol->ClassificationRequests );
dprintf( " Patterns Classified = %d\n", pProtocol->PatternsClassified );
dprintf( " Packets Classified = %d\n", pProtocol->PacketsClassified );
dprintf( "\n" );
dprintf( " Deref Patterns to zero = %d\n", pProtocol->DerefPattern2Zero );
dprintf( " First Frags Count = %d\n", pProtocol->FirstFragsCount );
dprintf( " Last Frags Count = %d\n", pProtocol->LastFragsCount );
dprintf( "\n" );
dprintf( " Inserted PH= %d\n", pProtocol->InsertedPH );
dprintf( " Removed PH= %d\n", pProtocol->RemovedPH );
dprintf( " Inserted Rz= %d\n", pProtocol->InsertedRz );
dprintf( " Removed Rz= %d\n", pProtocol->RemovedRz );
dprintf( " Inserted CH= %d\n", pProtocol->InsertedCH );
dprintf( " Removed CH= %d\n", pProtocol->RemovedCH );
}
DECLARE_API( pattern )
/*++
Function Description:
This function prints all the pattern in the QoS CF list.
If args is specified it is used as the blob addr.
--*/
{
DWORD TargetGlobalData;
GLOBAL_BLOCK LocalGlobalData;
PLIST_ENTRY pHead, pEntry;
DWORD TargetCf;
CF_BLOCK LocalCf;
ULONG result;
ULONG TargetPattern = 0;
PATTERN_BLOCK LocalPattern;
char *lerr;
if ( args )
TargetPattern = GetExpression( args );
if (TargetPattern) {
if ( !ReadMemory( TargetPattern,
&LocalPattern,
sizeof(LocalPattern),
&result ) ) {
dprintf( "Can't read memory from 0x%x", TargetPattern );
} else {
PrintPattern( &LocalPattern );
}
return;
}
#if 0
//
// scan the blob list for the QoS CF
//
TargetGlobalData = GetExpression( "MSGPC!glData" );
if( !TargetGlobalData )
{
dprintf( "Can't find the address of 'glData'" );
return;
}
//
if ( !ReadMemory(
TargetGlobalData,
&LocalGlobalData,
sizeof(LocalGlobalData),
&result
)) {
dprintf( "Can't read memory from 0x%x", TargetGlobalData );
return;
}
//
//
//
pHead = (PLIST_ENTRY)((PUCHAR)TargetGlobalData + FIELD_OFFSET(GLOBAL_BLOCK, CfList));
pEntry = LocalGlobalData.CfList.Flink;
while ( pHead != pEntry ) {
TargetCf = (DWORD)CONTAINING_RECORD( pEntry, CF_BLOCK, Linkage );
if ( !ReadMemory( TargetCf,
&LocalCf,
sizeof(LocalCf),
&result ) ) {
dprintf( "Can't read memory from 0x%x", TargetCf );
} else if ( CfIndex == (-1) || LocalCf.AssignedIndex == CfIndex ) {
PrintCf( &LocalCf );
}
pEntry = LocalCf.Linkage.Flink;
}
#endif
}
DECLARE_API( stat )
/*++
Function Description:
This function prints all the stat structure
--*/
{
DWORD TargetStat;
GPC_STAT LocalStat;
PLIST_ENTRY pHead, pEntry;
DWORD TargetCf;
CF_BLOCK LocalCf;
ULONG result;
TargetStat = GetExpression( "MSGPC!glStat" );
if( !TargetStat )
{
dprintf( "Can't find the address of 'glStat'" );
return;
}
if ( !ReadMemory( TargetStat,
&LocalStat,
sizeof(LocalStat),
&result ) ) {
dprintf( "Can't read memory from 0x%x", TargetStat );
} else {
PrintStat( &LocalStat );
}
}
DECLARE_API( autopatterns )
/*++
Function Description:
This function prints all the CF in the list. If args is specified, only that CF
will be printed. Currently these are supported:
0 - for CF_QOS
--*/
{
DWORD TargetGlobalData, TargetProtocolBlock;
GLOBAL_BLOCK LocalGlobalData;
PROTOCOL_BLOCK LocalProtocolBlock;
PLIST_ENTRY pHead, pEntry;
LIST_ENTRY listentry;
DWORD TargetPattern;
PATTERN_BLOCK LocalPattern;
ULONG result;
INT i, j;
ULONG CfIndex = (-1);
char *lerr;
TargetGlobalData = GetExpression( "MSGPC!glData" );
if( !TargetGlobalData )
{
dprintf( "Can't find the address of 'glData'" );
return;
}
//
if ( !ReadMemory(
TargetGlobalData,
&LocalGlobalData,
sizeof(LocalGlobalData),
&result
)) {
dprintf( "Can't read memory from 0x%x", TargetGlobalData );
return;
}
//
//
//
TargetProtocolBlock = (DWORD) LocalGlobalData.pProtocols;
if ( !ReadMemory(
TargetProtocolBlock,
&LocalProtocolBlock,
sizeof(LocalProtocolBlock),
&result
)) {
dprintf( "Can't read memory from 0x%x", TargetProtocolBlock );
return;
}
for (i = 0; i < NUMBER_OF_WHEELS; i++) {
j = 0;
pHead = (PLIST_ENTRY) ((DWORD)TargetProtocolBlock + (i * sizeof(listentry)));
pEntry = LocalProtocolBlock.TimerPatternList[i].Flink;
dprintf("Printing TimerWheel %d Head = %X and pEntry = %X ******************\n", i, pHead, pEntry);
while ( (pHead != pEntry) && (j < 1000) ) {
j++;
TargetPattern = (DWORD)CONTAINING_RECORD( pEntry, PATTERN_BLOCK, TimerLinkage );
if ( !ReadMemory( TargetPattern,
&LocalPattern,
sizeof(LocalPattern),
&result ) ) {
dprintf( "Can't read memory from 0x%x", TargetPattern );
} else {
dprintf("Pattern = %X and ClassificationBlock = %X\n", TargetPattern, LocalPattern.pClassificationBlock);
// PrintPattern( &LocalPattern );
}
pEntry = LocalPattern.TimerLinkage.Flink;
}
}
dprintf("Done printing all Timer Wheels\n");
}