763 lines
20 KiB
C++
763 lines
20 KiB
C++
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1995-1997 Microsoft Corporation
|
|||
|
|
|||
|
Module Name :
|
|||
|
|
|||
|
dbgatq.cxx
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains the NTSD Debugger extensions for the
|
|||
|
Asynchronous Thread Queue DLL
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Murali R. Krishnan ( MuraliK ) 12-May-1997
|
|||
|
|
|||
|
Environment:
|
|||
|
Debugger Mode - inside NT command line debuggers
|
|||
|
|
|||
|
Project:
|
|||
|
|
|||
|
Internet Server Debugging DLL
|
|||
|
|
|||
|
Functions Exported:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
|
|||
|
/************************************************************
|
|||
|
* Include Headers
|
|||
|
************************************************************/
|
|||
|
|
|||
|
|
|||
|
#include "inetdbgp.h"
|
|||
|
|
|||
|
|
|||
|
/************************************************************
|
|||
|
* Definitions of Variables & Macros
|
|||
|
************************************************************/
|
|||
|
|
|||
|
//
|
|||
|
// Text names of ATQ_SOCK_STATE values
|
|||
|
//
|
|||
|
|
|||
|
char * AtqSockState[] = {
|
|||
|
"ATQ_SOCK_CLOSED",
|
|||
|
"ATQ_SOCK_UNCONNECTED",
|
|||
|
"ATQ_SOCK_LISTENING",
|
|||
|
"ATQ_SOCK_CONNECTED"
|
|||
|
};
|
|||
|
|
|||
|
char * AtqEndpointState[] = {
|
|||
|
"AtqStateInit",
|
|||
|
"AtqStateActive",
|
|||
|
"AtqStateClosed",
|
|||
|
"AtqStateMax",
|
|||
|
};
|
|||
|
|
|||
|
#define LookupSockState( SockState ) \
|
|||
|
((SockState) <= ATQ_SOCK_CONNECTED ? AtqSockState[ (SockState) ] :\
|
|||
|
"<Invalid>")
|
|||
|
|
|||
|
|
|||
|
/************************************************************
|
|||
|
* Functions
|
|||
|
************************************************************/
|
|||
|
|
|||
|
VOID
|
|||
|
DumpAtqGlobals(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
DumpAtqContextList(
|
|||
|
CHAR Level,
|
|||
|
CHAR Verbosity,
|
|||
|
ATQ_ENDPOINT * pEndpointIn
|
|||
|
);
|
|||
|
|
|||
|
void
|
|||
|
DumpEndpointList(
|
|||
|
LIST_ENTRY * pAtqClientHead,
|
|||
|
CHAR Level,
|
|||
|
DWORD * pcContext,
|
|||
|
BYTE * pvStart,
|
|||
|
BYTE * pvEnd,
|
|||
|
ATQ_ENDPOINT * pEndpointIn
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
PrintAtqContext(
|
|||
|
ATQ_CONTEXT * AtqContext
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
PrintEndpoint(
|
|||
|
ATQ_ENDPOINT * pEp
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
DumpEndpoint(
|
|||
|
CHAR Level
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
DECLARE_API( atq )
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function is called as an NTSD extension to format and dump
|
|||
|
an object attributes structure.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hCurrentProcess - Supplies a handle to the current process (at the
|
|||
|
time the extension was called).
|
|||
|
|
|||
|
hCurrentThread - Supplies a handle to the current thread (at the
|
|||
|
time the extension was called).
|
|||
|
|
|||
|
CurrentPc - Supplies the current pc at the time the extension is
|
|||
|
called.
|
|||
|
|
|||
|
lpExtensionApis - Supplies the address of the functions callable
|
|||
|
by this extension.
|
|||
|
|
|||
|
lpArgumentString - Supplies the asciiz string that describes the
|
|||
|
ansi string to be dumped.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
BOOL fRet;
|
|||
|
ATQ_CONTEXT AtqContext;
|
|||
|
ATQ_CONTEXT * pAtqContext;
|
|||
|
|
|||
|
INIT_API();
|
|||
|
|
|||
|
while (*lpArgumentString == ' ')
|
|||
|
lpArgumentString++;
|
|||
|
|
|||
|
if ( !*lpArgumentString )
|
|||
|
{
|
|||
|
PrintUsage( "atq" );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if ( *lpArgumentString == '-' )
|
|||
|
{
|
|||
|
lpArgumentString++;
|
|||
|
|
|||
|
switch ( *lpArgumentString ) {
|
|||
|
|
|||
|
|
|||
|
case 'g':
|
|||
|
{
|
|||
|
DumpAtqGlobals();
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case 'c':
|
|||
|
{
|
|||
|
DumpAtqContextList( lpArgumentString[1],
|
|||
|
lpArgumentString[2],
|
|||
|
NULL );
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case 'e':
|
|||
|
{
|
|||
|
|
|||
|
ATQ_ENDPOINT * pEndpoint;
|
|||
|
|
|||
|
// Arguments: -e<Level><Verbosity> <EndpointAddr>
|
|||
|
|
|||
|
pEndpoint = ((ATQ_ENDPOINT * )
|
|||
|
GetExpression( lpArgumentString + 4));
|
|||
|
if ( !pEndpoint ) {
|
|||
|
|
|||
|
dprintf( "inetdbg: Unable to evaluate "
|
|||
|
"EndpointAddr \"%s\"\n",
|
|||
|
lpArgumentString );
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
DumpAtqContextList( lpArgumentString[1],
|
|||
|
lpArgumentString[2],
|
|||
|
pEndpoint );
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case 'l':
|
|||
|
{
|
|||
|
DumpEndpoint( lpArgumentString[1] );
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case 'p':
|
|||
|
{
|
|||
|
//
|
|||
|
// Treat the argument as the address of an AtqEndpoint
|
|||
|
//
|
|||
|
|
|||
|
ATQ_ENDPOINT * pEndpoint;
|
|||
|
|
|||
|
// Arguments: -p <EndpointAddr>
|
|||
|
|
|||
|
pEndpoint = ((ATQ_ENDPOINT *)
|
|||
|
GetExpression( lpArgumentString + 2 )
|
|||
|
);
|
|||
|
|
|||
|
if ( !pEndpoint )
|
|||
|
{
|
|||
|
dprintf( "inetdbg: Unable to evaluate \"%s\"\n",
|
|||
|
lpArgumentString );
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ATQ_ENDPOINT Endpoint;
|
|||
|
move( Endpoint, pEndpoint );
|
|||
|
PrintEndpoint( &Endpoint );
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
default:
|
|||
|
case 'h':
|
|||
|
{
|
|||
|
PrintUsage( "atq" );
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
} // switch
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Treat the argument as the address of an AtqContext
|
|||
|
//
|
|||
|
|
|||
|
pAtqContext = (PATQ_CONT)GetExpression( lpArgumentString );
|
|||
|
|
|||
|
if ( !pAtqContext )
|
|||
|
{
|
|||
|
dprintf( "inetdbg: Unable to evaluate \"%s\"\n",
|
|||
|
lpArgumentString );
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
move( AtqContext, pAtqContext );
|
|||
|
PrintAtqContext( &AtqContext );
|
|||
|
} // DECLARE_API( atq )
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/************************************************************
|
|||
|
* ATQ related functions
|
|||
|
************************************************************/
|
|||
|
|
|||
|
VOID
|
|||
|
DumpAtqGlobals(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// Dump Atq Globals
|
|||
|
//
|
|||
|
|
|||
|
dprintf("Atq Globals:\n");
|
|||
|
|
|||
|
DumpDword( "isatq!g_cConcurrency " );
|
|||
|
DumpDword( "isatq!g_cThreads " );
|
|||
|
DumpDword( "isatq!g_cAvailableThreads " );
|
|||
|
DumpDword( "isatq!g_cMaxThreads " );
|
|||
|
|
|||
|
dprintf("\n");
|
|||
|
DumpDword( "isatq!g_fUseAcceptEx " );
|
|||
|
DumpDword( "isatq!g_fUseTransmitFile " );
|
|||
|
DumpDword( "isatq!g_cbXmitBufferSize " );
|
|||
|
DumpDword( "isatq!g_cbMinKbSec " );
|
|||
|
DumpDword( "isatq!g_cCPU " );
|
|||
|
DumpDword( "isatq!g_fShutdown " );
|
|||
|
dprintf("\n");
|
|||
|
|
|||
|
DumpDword( "isatq!g_msThreadTimeout " );
|
|||
|
DumpDword( "isatq!g_dwTimeoutCookie " );
|
|||
|
DumpDword( "isatq!g_cListenBacklog " );
|
|||
|
DumpDword( "isatq!AtqCurrentTick " );
|
|||
|
DumpDword( "isatq!AtqGlobalContextCount" );
|
|||
|
dprintf("\tsizeof(ATQ_CONTEXT) = %d\n", sizeof(ATQ_CONTEXT));
|
|||
|
|
|||
|
return;
|
|||
|
} // DumpAtqGlobals()
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
DumpAtqContextList(
|
|||
|
CHAR Level,
|
|||
|
CHAR Verbosity,
|
|||
|
ATQ_ENDPOINT * pEndpointIn
|
|||
|
)
|
|||
|
{
|
|||
|
LIST_ENTRY AtqClientHead;
|
|||
|
LIST_ENTRY * pAtqClientHead;
|
|||
|
ATQ_CONTEXT * pAtqContext;
|
|||
|
ATQ_CONTEXT AtqContext;
|
|||
|
CHAR Symbol[256];
|
|||
|
DWORD cContext = 0;
|
|||
|
DWORD cc1;
|
|||
|
ATQ_CONTEXT_LISTHEAD * pAtqActiveContextList;
|
|||
|
ATQ_CONTEXT_LISTHEAD AtqActiveContextList[ATQ_NUM_CONTEXT_LIST];
|
|||
|
DWORD i;
|
|||
|
|
|||
|
pAtqActiveContextList =
|
|||
|
(ATQ_CONTEXT_LISTHEAD *) GetExpression( "&isatq!AtqActiveContextList" );
|
|||
|
|
|||
|
if ( !pAtqActiveContextList )
|
|||
|
{
|
|||
|
dprintf("Unable to get AtqActiveContextList symbol\n" );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if ( !ReadMemory( (LPVOID) pAtqActiveContextList,
|
|||
|
AtqActiveContextList,
|
|||
|
sizeof(AtqActiveContextList),
|
|||
|
NULL ))
|
|||
|
{
|
|||
|
dprintf("Unable to read AtqActiveContextList memory\n" );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
for ( i = 0; i < ATQ_NUM_CONTEXT_LIST; i++ )
|
|||
|
{
|
|||
|
dprintf("================================================\n");
|
|||
|
dprintf("== Context List %d ==\n", i );
|
|||
|
dprintf("================================================\n");
|
|||
|
|
|||
|
dprintf(" Active List ==>\n" );
|
|||
|
|
|||
|
cc1 = 0;
|
|||
|
DumpEndpointList( &(AtqActiveContextList[i].ActiveListHead),
|
|||
|
Verbosity,
|
|||
|
&cc1,
|
|||
|
(BYTE *) pAtqActiveContextList,
|
|||
|
(BYTE *) &pAtqActiveContextList[ATQ_NUM_CONTEXT_LIST],
|
|||
|
pEndpointIn
|
|||
|
);
|
|||
|
|
|||
|
if ( 0 != cc1) {
|
|||
|
dprintf( "\n\t%d Atq contexts traversed\n", cc1 );
|
|||
|
cContext += cc1;
|
|||
|
}
|
|||
|
|
|||
|
if ( Level >= '1' )
|
|||
|
{
|
|||
|
dprintf("================================================\n");
|
|||
|
dprintf("Pending AcceptEx List\n");
|
|||
|
|
|||
|
cc1 = 0;
|
|||
|
DumpEndpointList( &(AtqActiveContextList[i].PendingAcceptExListHead),
|
|||
|
Verbosity,
|
|||
|
&cc1,
|
|||
|
(BYTE *) pAtqActiveContextList,
|
|||
|
(BYTE *) &pAtqActiveContextList[ATQ_NUM_CONTEXT_LIST],
|
|||
|
pEndpointIn
|
|||
|
);
|
|||
|
if ( 0 != cc1) {
|
|||
|
dprintf( "\n\t%d Atq contexts traversed\n", cc1 );
|
|||
|
cContext += cc1;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( CheckControlC() )
|
|||
|
{
|
|||
|
dprintf( "\n^C\n" );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
dprintf( "%d Atq contexts traversed\n",
|
|||
|
cContext );
|
|||
|
|
|||
|
return;
|
|||
|
} // DumpAtqContextList()
|
|||
|
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
DumpEndpointList(
|
|||
|
LIST_ENTRY * pAtqClientHead,
|
|||
|
CHAR Verbosity,
|
|||
|
DWORD * pcContext,
|
|||
|
BYTE * pvStart,
|
|||
|
BYTE * pvEnd,
|
|||
|
ATQ_ENDPOINT * pEndpointIn
|
|||
|
)
|
|||
|
{
|
|||
|
LIST_ENTRY * pEntry;
|
|||
|
ATQ_CONTEXT * pAtqContext;
|
|||
|
ATQ_CONTEXT AtqContext;
|
|||
|
|
|||
|
//
|
|||
|
// the list head is embedded in a structure so the exit condition of the
|
|||
|
// loop is when the remote memory address ends up in the array memory
|
|||
|
//
|
|||
|
|
|||
|
for ( pEntry = pAtqClientHead->Flink;
|
|||
|
!((BYTE *)pEntry >= pvStart && (BYTE *)pEntry <= pvEnd);
|
|||
|
)
|
|||
|
{
|
|||
|
if ( CheckControlC() )
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
pAtqContext = CONTAINING_RECORD( pEntry,
|
|||
|
ATQ_CONTEXT,
|
|||
|
m_leTimeout );
|
|||
|
|
|||
|
move( AtqContext, pAtqContext );
|
|||
|
|
|||
|
// selectively print only the contexts that have a matching Endpoint
|
|||
|
if ( (pEndpointIn != NULL) &&
|
|||
|
(AtqContext.pEndpoint != pEndpointIn)
|
|||
|
) {
|
|||
|
|
|||
|
move( pEntry, &pEntry->Flink );
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
(*pcContext)++;
|
|||
|
|
|||
|
if ( AtqContext.Signature != ATQ_CONTEXT_SIGNATURE )
|
|||
|
{
|
|||
|
dprintf( "AtqContext(%08lp) signature %08lx doesn't"
|
|||
|
" match expected %08lx\n",
|
|||
|
pAtqContext,
|
|||
|
AtqContext.Signature,
|
|||
|
ATQ_CONTEXT_SIGNATURE
|
|||
|
);
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if ( Verbosity >= '1' )
|
|||
|
{
|
|||
|
//
|
|||
|
// Print all
|
|||
|
//
|
|||
|
|
|||
|
dprintf( "\nAtqContext at %08lp\n",
|
|||
|
pAtqContext );
|
|||
|
|
|||
|
PrintAtqContext( &AtqContext );
|
|||
|
|
|||
|
}
|
|||
|
else if ( Verbosity >= '0' )
|
|||
|
{
|
|||
|
//
|
|||
|
// Print all with one line summary info
|
|||
|
//
|
|||
|
|
|||
|
dprintf( "hAsyncIO = %4lp, Flink = %08lp, Blink = %08lp,"
|
|||
|
" State = %8lx, Flags =%8lx\n",
|
|||
|
AtqContext.hAsyncIO,
|
|||
|
AtqContext.m_leTimeout.Blink,
|
|||
|
AtqContext.m_leTimeout.Flink,
|
|||
|
AtqContext.m_acState,
|
|||
|
AtqContext.m_acFlags
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
move( pEntry, &pEntry->Flink );
|
|||
|
}
|
|||
|
} // DumpEndpointList()
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
PrintAtqContext(
|
|||
|
ATQ_CONTEXT * pContext
|
|||
|
)
|
|||
|
{
|
|||
|
UCHAR szSymFnCallback[MAX_SYMBOL_LEN];
|
|||
|
ULONG_PTR offset;
|
|||
|
|
|||
|
|
|||
|
GetSymbol((ULONG_PTR) pContext->pfnCompletion,
|
|||
|
szSymFnCallback, &offset);
|
|||
|
|
|||
|
if (!*szSymFnCallback)
|
|||
|
sprintf((char*) szSymFnCallback, "%p()",
|
|||
|
pContext->pfnCompletion);
|
|||
|
|
|||
|
dprintf( "\n" );
|
|||
|
dprintf( "\thAsyncIO = %08lp Signature = %08lx\n"
|
|||
|
"\tOverlapped.Internal = %08lp Overlapped.Offset= %08lx\n"
|
|||
|
"\tLE-Timeout.Flink = %08lp LE-Timeout.Blink = %p\n"
|
|||
|
"\tClientContext = %08lp ContextList = %p\n"
|
|||
|
"\tpfnIOCompletion = %s\n"
|
|||
|
"\tlSyncTimeout = %8d m_nIO = %8d\n"
|
|||
|
"\tTimeOut = %08lx NextTimeout = %08lx\n"
|
|||
|
"\tBytesSent = %d (0x%08lx)\n"
|
|||
|
"\tpvBuff = %08lp pEndPoint = %08lp\n"
|
|||
|
"\tState = %8lx Flags = %08lx\n",
|
|||
|
pContext->hAsyncIO, pContext->Signature,
|
|||
|
pContext->Overlapped.Internal,pContext->Overlapped.Offset,
|
|||
|
pContext->m_leTimeout.Flink, pContext->m_leTimeout.Blink,
|
|||
|
pContext->ClientContext, pContext->ContextList,
|
|||
|
szSymFnCallback,
|
|||
|
pContext->lSyncTimeout, pContext->m_nIO,
|
|||
|
pContext->TimeOut, pContext->NextTimeout,
|
|||
|
pContext->BytesSent, pContext->BytesSent,
|
|||
|
pContext->pvBuff, pContext->pEndpoint,
|
|||
|
pContext->m_acState, pContext->m_acFlags
|
|||
|
);
|
|||
|
|
|||
|
// identify and print the various properties
|
|||
|
dprintf( "\t");
|
|||
|
// First print the state bits
|
|||
|
if ( pContext->m_acState & ACS_SOCK_CLOSED) {
|
|||
|
dprintf( " ACS_SOCK_CLOSED");
|
|||
|
}
|
|||
|
if ( pContext->m_acState & ACS_SOCK_UNCONNECTED) {
|
|||
|
dprintf( " ACS_SOCK_UNCONNECTED");
|
|||
|
}
|
|||
|
if ( pContext->m_acState & ACS_SOCK_LISTENING) {
|
|||
|
dprintf( " ACS_SOCK_LISTENING");
|
|||
|
}
|
|||
|
if ( pContext->m_acState & ACS_SOCK_CONNECTED) {
|
|||
|
dprintf( " ACS_SOCK_CONNECTED");
|
|||
|
}
|
|||
|
if ( pContext->m_acState & ACS_SOCK_TOBE_FREED) {
|
|||
|
dprintf( " ACS_SOCK_TOBE_FREED");
|
|||
|
}
|
|||
|
|
|||
|
// now print the flags associated with this context
|
|||
|
if ( pContext->m_acFlags & ACF_ACCEPTEX_ROOT_CONTEXT) {
|
|||
|
dprintf( " ACCEPTEX_CONTEXT");
|
|||
|
}
|
|||
|
if ( pContext->m_acFlags & ACF_CONN_INDICATED) {
|
|||
|
dprintf( " CONNECTION_INDICATED");
|
|||
|
}
|
|||
|
if ( pContext->m_acFlags & ACF_IN_TIMEOUT) {
|
|||
|
dprintf( " IN_TIMEOUT");
|
|||
|
}
|
|||
|
if ( pContext->m_acFlags & ACF_BLOCKED) {
|
|||
|
dprintf( " BLOCKED_BY_BWT");
|
|||
|
}
|
|||
|
if ( pContext->m_acFlags & ACF_REUSE_CONTEXT) {
|
|||
|
dprintf( " REUSE_CONTEXT");
|
|||
|
}
|
|||
|
if ( pContext->m_acFlags & ACF_RECV_ISSUED) {
|
|||
|
dprintf( " RECV_ISSUED");
|
|||
|
}
|
|||
|
if ( pContext->m_acFlags & ACF_ABORTIVE_CLOSE) {
|
|||
|
dprintf( " ABORTIVE_CLOSE");
|
|||
|
}
|
|||
|
dprintf( "\n");
|
|||
|
|
|||
|
if ( pContext->IsFlag( ACF_ACCEPTEX_ROOT_CONTEXT) && pContext->pvBuff )
|
|||
|
{
|
|||
|
//
|
|||
|
// This size should correspond to the MIN_SOCKADDR_SIZE field in
|
|||
|
// atqnew.c. We assume it's two thirty two byte values currently.
|
|||
|
//
|
|||
|
|
|||
|
DWORD AddrInfo[16];
|
|||
|
ATQ_ENDPOINT * pEndpoint = pContext->pEndpoint;
|
|||
|
ATQ_ENDPOINT Endpoint;
|
|||
|
|
|||
|
move( Endpoint, pEndpoint );
|
|||
|
|
|||
|
if ( ReadMemory( (LPVOID) ((BYTE *) pContext->pvBuff +
|
|||
|
Endpoint.InitialRecvSize +
|
|||
|
2 * MIN_SOCKADDR_SIZE -
|
|||
|
sizeof( AddrInfo )),
|
|||
|
AddrInfo,
|
|||
|
sizeof(AddrInfo),
|
|||
|
NULL ))
|
|||
|
{
|
|||
|
|
|||
|
dprintf( "\tLocal/Remote Addr = %08x %08x %08x %08x\n"
|
|||
|
"\t %08x %08x %08x %08x\n"
|
|||
|
"\t %08x %08x %08x %08x\n"
|
|||
|
"\t %08x %08x %08x %08x\n",
|
|||
|
AddrInfo[0],
|
|||
|
AddrInfo[1],
|
|||
|
AddrInfo[2],
|
|||
|
AddrInfo[3],
|
|||
|
AddrInfo[4],
|
|||
|
AddrInfo[5],
|
|||
|
AddrInfo[6],
|
|||
|
AddrInfo[7],
|
|||
|
AddrInfo[8],
|
|||
|
AddrInfo[9],
|
|||
|
AddrInfo[10],
|
|||
|
AddrInfo[11],
|
|||
|
AddrInfo[12],
|
|||
|
AddrInfo[13],
|
|||
|
AddrInfo[14],
|
|||
|
AddrInfo[15] );
|
|||
|
}
|
|||
|
}
|
|||
|
} // PrintAtqContext()
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
DumpEndpoint(
|
|||
|
CHAR Verbosity
|
|||
|
)
|
|||
|
{
|
|||
|
LIST_ENTRY AtqEndpointList;
|
|||
|
LIST_ENTRY * pAtqEndpointList;
|
|||
|
LIST_ENTRY * pEntry;
|
|||
|
ATQ_CONTEXT * pAtqContext;
|
|||
|
ATQ_CONTEXT AtqContext;
|
|||
|
CHAR Symbol[256];
|
|||
|
DWORD cEndp = 0;
|
|||
|
DWORD i;
|
|||
|
ATQ_ENDPOINT * pEndpoint;
|
|||
|
ATQ_ENDPOINT Endpoint;
|
|||
|
|
|||
|
pAtqEndpointList = (LIST_ENTRY *) GetExpression( "&isatq!AtqEndpointList" );
|
|||
|
|
|||
|
if ( !pAtqEndpointList )
|
|||
|
{
|
|||
|
dprintf("Unable to get AtqEndpointList symbol\n" );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
move( AtqEndpointList, pAtqEndpointList );
|
|||
|
|
|||
|
for ( pEntry = AtqEndpointList.Flink;
|
|||
|
pEntry != pAtqEndpointList;
|
|||
|
cEndp++
|
|||
|
)
|
|||
|
{
|
|||
|
if ( CheckControlC() )
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
pEndpoint = CONTAINING_RECORD( pEntry,
|
|||
|
ATQ_ENDPOINT,
|
|||
|
ListEntry );
|
|||
|
|
|||
|
move( Endpoint, pEndpoint );
|
|||
|
|
|||
|
if ( Endpoint.Signature != ATQ_ENDPOINT_SIGNATURE )
|
|||
|
{
|
|||
|
dprintf( "Endpoint(%08p) signature %08lx doesn't match expected %08lx\n",
|
|||
|
pEndpoint,
|
|||
|
Endpoint.Signature,
|
|||
|
ATQ_ENDPOINT_SIGNATURE
|
|||
|
);
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if ( Verbosity >= '1' )
|
|||
|
{
|
|||
|
//
|
|||
|
// Print all
|
|||
|
//
|
|||
|
|
|||
|
dprintf( "\nEndpoint at %08lp\n",
|
|||
|
pEndpoint );
|
|||
|
|
|||
|
PrintEndpoint( &Endpoint );
|
|||
|
|
|||
|
}
|
|||
|
else if ( Verbosity >= '0' )
|
|||
|
{
|
|||
|
//
|
|||
|
// Print all with one line summary info
|
|||
|
//
|
|||
|
|
|||
|
dprintf( "sListenSocket = %4lp, cRef = %d, cSocketsAvail = %d\n",
|
|||
|
Endpoint.ListenSocket,
|
|||
|
Endpoint.m_refCount,
|
|||
|
Endpoint.nSocketsAvail );
|
|||
|
}
|
|||
|
|
|||
|
move( pEntry, &pEntry->Flink );
|
|||
|
}
|
|||
|
|
|||
|
dprintf( "%d Atq Endpoints traversed\n",
|
|||
|
cEndp );
|
|||
|
|
|||
|
return;
|
|||
|
} // DumpEndpoint()
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
PrintEndpoint(
|
|||
|
ATQ_ENDPOINT * pEp
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
dprintf( "\tcRef = %8d State = %s\n"
|
|||
|
"\tIP Address = %s Port = %04x\n"
|
|||
|
"\tsListenSocket = %8p InitRecvSize = %04x\n"
|
|||
|
"\tnSocketsAvail = %8d nAvailAtTimeout = %d\n"
|
|||
|
"\tnAcceptExOutstdg =%8d\n"
|
|||
|
"\tUseAcceptEx = %8s AcceptExTimeout = %8d\n"
|
|||
|
"\tEnableBw Throttle= %s\n"
|
|||
|
"\tListEntry.Flink = %08lp ListEntry.Blink = %08lp\n"
|
|||
|
"\tClient Context = %08lp pfnCompletion = %08lp()\n"
|
|||
|
"\tpfnConnComp = %08lp() pfnConnExComp = %08lp()\n"
|
|||
|
"\tShutDownCallback = %08lp() ShutDown Context = %08lp\n"
|
|||
|
,
|
|||
|
pEp->m_refCount,
|
|||
|
AtqEndpointState[pEp->State],
|
|||
|
pEp->IpAddress,
|
|||
|
pEp->Port,
|
|||
|
pEp->ListenSocket,
|
|||
|
pEp->InitialRecvSize,
|
|||
|
pEp->nSocketsAvail,
|
|||
|
pEp->nAvailDuringTimeOut,
|
|||
|
pEp->nAcceptExOutstanding,
|
|||
|
BoolValue( pEp->UseAcceptEx),
|
|||
|
pEp->AcceptExTimeout,
|
|||
|
BoolValue( pEp->EnableBw),
|
|||
|
pEp->ListEntry.Flink,
|
|||
|
pEp->ListEntry.Blink,
|
|||
|
pEp->Context,
|
|||
|
pEp->IoCompletion,
|
|||
|
pEp->ConnectCompletion,
|
|||
|
pEp->ConnectExCompletion,
|
|||
|
pEp->ShutdownCallback,
|
|||
|
pEp->ShutdownCallbackContext
|
|||
|
);
|
|||
|
|
|||
|
return;
|
|||
|
} // PrintEndpoint()
|
|||
|
|
|||
|
|
|||
|
/************************ End of File ***********************/
|
|||
|
|