734 lines
19 KiB
C++
734 lines
19 KiB
C++
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1995-1997 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
dbgcc.cxx
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains the default ntsd debugger extensions for
|
|||
|
IIS - W3SVC Client Connection
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Murali R. Krishnan (MuraliK) 22-Aug-1997
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "inetdbgp.h"
|
|||
|
|
|||
|
# undef DBG_ASSERT
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/************************************************************
|
|||
|
* Debugger Utility Functions
|
|||
|
************************************************************/
|
|||
|
|
|||
|
NTSD_EXTENSION_APIS ExtensionApis;
|
|||
|
HANDLE ExtensionCurrentProcess;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/************************************************************
|
|||
|
* CLIENT_CONN related functions
|
|||
|
************************************************************/
|
|||
|
char * g_rgchCCState[] = {
|
|||
|
"CcsStartup",
|
|||
|
"CcsGettingClientReq",
|
|||
|
"CcsGatheringGatewayData",
|
|||
|
"CcsProcessingClientReq",
|
|||
|
"CcsDisconnecting",
|
|||
|
"CcsShutdown",
|
|||
|
"CcsMaxItems"
|
|||
|
};
|
|||
|
|
|||
|
#define LookupCCState( ItemState ) \
|
|||
|
((((ItemState) >= CCS_STARTUP) && ((ItemState) <= CCS_SHUTDOWN)) ?\
|
|||
|
g_rgchCCState[ (ItemState)] : "<Invalid>")
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID PrintClientConn( CLIENT_CONN * pccOriginal,
|
|||
|
CLIENT_CONN * pcc, CHAR Verbosity);
|
|||
|
|
|||
|
VOID
|
|||
|
PrintClientConnThunk( PVOID pccDebuggee,
|
|||
|
PVOID pccDebugger,
|
|||
|
CHAR verbosity,
|
|||
|
DWORD iCount);
|
|||
|
|
|||
|
|
|||
|
DECLARE_API( cc )
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
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;
|
|||
|
DEFINE_CPP_VAR( CLIENT_CONN, cc);
|
|||
|
CLIENT_CONN * pcc;
|
|||
|
|
|||
|
INIT_API();
|
|||
|
|
|||
|
while (*lpArgumentString == ' ')
|
|||
|
lpArgumentString++;
|
|||
|
|
|||
|
if ( !*lpArgumentString )
|
|||
|
{
|
|||
|
PrintUsage( "cc" );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if ( *lpArgumentString == '-' )
|
|||
|
{
|
|||
|
lpArgumentString++;
|
|||
|
|
|||
|
if ( *lpArgumentString == 'h' )
|
|||
|
{
|
|||
|
PrintUsage( "cc" );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if ( *lpArgumentString == 'l' ) {
|
|||
|
|
|||
|
DumpClientConnList( lpArgumentString[1], PrintClientConnThunk );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
} // while
|
|||
|
|
|||
|
//
|
|||
|
// Treat the argument as the address of an AtqContext
|
|||
|
//
|
|||
|
|
|||
|
pcc = (CLIENT_CONN * ) GetExpression( lpArgumentString );
|
|||
|
|
|||
|
if ( !pcc )
|
|||
|
{
|
|||
|
dprintf( "inetdbg.cc: Unable to evaluate \"%s\"\n",
|
|||
|
lpArgumentString );
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
move( cc, pcc );
|
|||
|
PrintClientConn( pcc, GET_CPP_VAR_PTR( CLIENT_CONN, cc), '2' );
|
|||
|
|
|||
|
return;
|
|||
|
} // DECLARE_API( cc )
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
PrintClientConn( CLIENT_CONN * pccOriginal,
|
|||
|
CLIENT_CONN * pcc,
|
|||
|
CHAR Verbosity )
|
|||
|
/*++
|
|||
|
Description:
|
|||
|
This function takes the client connection object and prints out
|
|||
|
the details for the same in the debugger. The granularity of the
|
|||
|
deatils are controlled by the verbosity flag
|
|||
|
|
|||
|
Arguments:
|
|||
|
pccOriginal - pointer to the location where the original CLIENT_CONN
|
|||
|
object is located.
|
|||
|
Note: pccOriginal points to object inside debuggee process
|
|||
|
pcc - pointer to the Client Connection object that is a copy
|
|||
|
of the contents located at [pccOriginal]
|
|||
|
Note: pcc points to object inside the debugger process
|
|||
|
Verbostiy - level of details requested.
|
|||
|
|
|||
|
Returns:
|
|||
|
None
|
|||
|
--*/
|
|||
|
{
|
|||
|
if ( Verbosity >= '0') {
|
|||
|
|
|||
|
//
|
|||
|
// print Brief information about the client connection
|
|||
|
//
|
|||
|
|
|||
|
dprintf( "ClIENT_CONN:%08p Refs = %8d State = %15s\n"
|
|||
|
"\t HTTP_REQUEST = %08p AtqContext = %08p\n"
|
|||
|
,
|
|||
|
pccOriginal, pcc->_cRef,
|
|||
|
LookupCCState( pcc->_ccState),
|
|||
|
pcc->_phttpReq,
|
|||
|
pcc->_AtqContext
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
if ( Verbosity >= '1' ) {
|
|||
|
|
|||
|
//
|
|||
|
// Print all details for the Client Connection object
|
|||
|
//
|
|||
|
|
|||
|
|
|||
|
dprintf( "\tSignature = %08x fSecurePort=%d fValid=%d; \n"
|
|||
|
"\tSocket = %08p Port: Local=%hd Remote=%hd\n"
|
|||
|
"\tListEntry.Flink = %08p ListEntry.Blink = %08p\n"
|
|||
|
"\tInitialBuffer = %08p InitialBytesRecvd = %d\n"
|
|||
|
"\tBuffLE.Flink = %08p BuffLE.Blink = %08p\n"
|
|||
|
"\tAddress Local = %10s Address Remote = %10s\n"
|
|||
|
"\tW3Instance = %08p Reflog = %08p\n"
|
|||
|
,
|
|||
|
pcc->_Signature, pcc->_fSecurePort, pcc->_fIsValid,
|
|||
|
pcc->_sClient, pcc->_sPort, pcc->_sRemotePort,
|
|||
|
pcc->ListEntry.Flink, pcc->ListEntry.Blink,
|
|||
|
pcc->_pvInitial, pcc->_cbInitial,
|
|||
|
pcc->_BuffListEntry.Flink, pcc->_BuffListEntry.Blink,
|
|||
|
pcc->_achLocalAddr, pcc->_achRemoteAddr,
|
|||
|
pcc->m_pInstance,
|
|||
|
#if CC_REF_TRACKING // Enabled in free builds for build 585 and later
|
|||
|
pcc->_pDbgCCRefTraceLog
|
|||
|
#else
|
|||
|
(PVOID)(-1)
|
|||
|
#endif
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if ( Verbosity >= '2' ) {
|
|||
|
|
|||
|
//
|
|||
|
// Print the initial request received for the client connection
|
|||
|
//
|
|||
|
|
|||
|
dstring( " Initial Request", pcc->_pvInitial, pcc->_cbInitial);
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
} // PrintClientConn()
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
PrintClientConnThunk( PVOID pccDebuggee,
|
|||
|
PVOID pccDebugger,
|
|||
|
CHAR verbosity,
|
|||
|
DWORD iThunk)
|
|||
|
/*++
|
|||
|
Description:
|
|||
|
This is the callback function for printing the CLIENT_CONN object.
|
|||
|
|
|||
|
Arguments:
|
|||
|
pccDebuggee - pointer to client conn object in the debuggee process
|
|||
|
pccDebugger - pointer to client conn object in the debugger process
|
|||
|
verbosity - character indicating the verbosity level desired
|
|||
|
|
|||
|
Returns:
|
|||
|
None
|
|||
|
--*/
|
|||
|
{
|
|||
|
if ( ((CLIENT_CONN * )pccDebugger)->_Signature != CLIENT_CONN_SIGNATURE) {
|
|||
|
|
|||
|
dprintf( "ClientConn(%08lp) signature %08lx doesn't"
|
|||
|
" match expected %08lx\n",
|
|||
|
pccDebuggee,
|
|||
|
((CLIENT_CONN * )pccDebugger)->_Signature,
|
|||
|
CLIENT_CONN_SIGNATURE
|
|||
|
);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
PrintClientConn( (CLIENT_CONN *) pccDebuggee,
|
|||
|
(CLIENT_CONN *) pccDebugger,
|
|||
|
verbosity);
|
|||
|
} // PrintClientConnThunk()
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
DumpClientConnList(
|
|||
|
CHAR Verbosity,
|
|||
|
PFN_LIST_ENUMERATOR pfnCC
|
|||
|
)
|
|||
|
{
|
|||
|
LIST_ENTRY * pccListHead;
|
|||
|
|
|||
|
pccListHead = (LIST_ENTRY *) GetExpression( "&w3svc!listConnections");
|
|||
|
|
|||
|
if ( NULL == pccListHead) {
|
|||
|
|
|||
|
dprintf( " Unable to get Client Connections list \n");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
EnumLinkedList( pccListHead, pfnCC, Verbosity,
|
|||
|
sizeof( CLIENT_CONN),
|
|||
|
FIELD_OFFSET( CLIENT_CONN, ListEntry)
|
|||
|
);
|
|||
|
|
|||
|
return;
|
|||
|
} // DumpClientConnList()
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/************************************************************
|
|||
|
* HTTP_REQUEST related functions
|
|||
|
************************************************************/
|
|||
|
char * g_rgchHREQState[] = {
|
|||
|
"HtrReadingClientRequest",
|
|||
|
"HtrReadingGatewayData",
|
|||
|
"HtrParse",
|
|||
|
"HtrDoVerb",
|
|||
|
"HtrGatewayAsyncIO",
|
|||
|
"HtrSendFile",
|
|||
|
"HtrProxySendingRequest",
|
|||
|
"HtrCgi",
|
|||
|
"HtrRange",
|
|||
|
"HtrRestartRequest",
|
|||
|
"HtrWritingFile",
|
|||
|
"HtrCertRenegotiate",
|
|||
|
"HtrMaxItems"
|
|||
|
};
|
|||
|
|
|||
|
#define LookupHREQState( ItemState ) \
|
|||
|
((((ItemState) >= HTR_READING_CLIENT_REQUEST) && \
|
|||
|
((ItemState) <= HTR_DONE)) ?\
|
|||
|
g_rgchHREQState[ (ItemState)] : "<Invalid>")
|
|||
|
|
|||
|
const char * g_rgchHreqPutState[] = {
|
|||
|
"PSTATE_START",
|
|||
|
"PSTATE_READING",
|
|||
|
"PSTATE_DISCARD_READING",
|
|||
|
"PSTATE_DISCARD_CHUNK"
|
|||
|
};
|
|||
|
|
|||
|
# define LookupHreqPutState( ItemState) \
|
|||
|
((((ItemState) >= PSTATE_START) && \
|
|||
|
((ItemState) <= PSTATE_DISCARD_CHUNK)) ?\
|
|||
|
g_rgchHreqPutState[ (ItemState)] : "<Invalid>")
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
PrintHttpRequest( HTTP_REQUEST * phreqOriginal,
|
|||
|
HTTP_REQUEST * phreq,
|
|||
|
CHAR Verbosity);
|
|||
|
|
|||
|
VOID
|
|||
|
PrintHttpRequestThunk( PVOID pccDebuggee,
|
|||
|
PVOID pccDebugger,
|
|||
|
CHAR verbosity,
|
|||
|
DWORD iCount);
|
|||
|
|
|||
|
|
|||
|
DECLARE_API( hreq )
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
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;
|
|||
|
DEFINE_CPP_VAR( HTTP_REQUEST, hreq);
|
|||
|
HTTP_REQUEST * phreq;
|
|||
|
|
|||
|
INIT_API();
|
|||
|
|
|||
|
while (*lpArgumentString == ' ')
|
|||
|
lpArgumentString++;
|
|||
|
|
|||
|
if ( !*lpArgumentString )
|
|||
|
{
|
|||
|
PrintUsage( "hreq" );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if ( *lpArgumentString == '-' )
|
|||
|
{
|
|||
|
lpArgumentString++;
|
|||
|
|
|||
|
if ( *lpArgumentString == 'h' )
|
|||
|
{
|
|||
|
PrintUsage( "hreq" );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if ( *lpArgumentString == 'l' ) {
|
|||
|
|
|||
|
DumpClientConnList( lpArgumentString[1],
|
|||
|
PrintHttpRequestThunk);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
} // if
|
|||
|
|
|||
|
//
|
|||
|
// Treat the argument as the address of an AtqContext
|
|||
|
//
|
|||
|
|
|||
|
phreq = (HTTP_REQUEST * ) GetExpression( lpArgumentString );
|
|||
|
|
|||
|
if ( !phreq )
|
|||
|
{
|
|||
|
dprintf( "inetdbg.hreq: Unable to evaluate \"%s\"\n",
|
|||
|
lpArgumentString );
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
move( hreq, phreq );
|
|||
|
PrintHttpRequest( phreq, GET_CPP_VAR_PTR( HTTP_REQUEST, hreq), '2');
|
|||
|
|
|||
|
return;
|
|||
|
} // DECLARE_API( hreq )
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
PrintHttpRequestThunk(
|
|||
|
PVOID pccDebuggee,
|
|||
|
PVOID pccDebugger,
|
|||
|
CHAR verbosity,
|
|||
|
DWORD iCount)
|
|||
|
/*++
|
|||
|
Description:
|
|||
|
This is the callback function for printing the HTTP_REQUEST object.
|
|||
|
|
|||
|
Arguments:
|
|||
|
pccDebuggee - pointer to client conn object in the debuggee process
|
|||
|
pccDebugger - pointer to client conn object in the debugger process
|
|||
|
verbosity - character indicating the verbosity level desired
|
|||
|
|
|||
|
Returns:
|
|||
|
None
|
|||
|
--*/
|
|||
|
{
|
|||
|
DEFINE_CPP_VAR( HTTP_REQUEST, hreq);
|
|||
|
HTTP_REQUEST * phreq;
|
|||
|
|
|||
|
CLIENT_CONN * pcc = (CLIENT_CONN *) pccDebugger;
|
|||
|
|
|||
|
if ( pcc->_Signature != CLIENT_CONN_SIGNATURE) {
|
|||
|
|
|||
|
dprintf( "ClientConn(%08lp) signature %08lx doesn't"
|
|||
|
" match expected %08lx\n",
|
|||
|
pccDebuggee,
|
|||
|
pcc->_Signature,
|
|||
|
CLIENT_CONN_SIGNATURE
|
|||
|
);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Obtain the pointer for HTTP_REQUEST object from CLIENT_CONN object
|
|||
|
// and make local copy of the HTTP_REQUEST object inside debugger process
|
|||
|
//
|
|||
|
phreq = (HTTP_REQUEST *) pcc->_phttpReq;
|
|||
|
move( hreq, phreq);
|
|||
|
|
|||
|
// Print out the http request object
|
|||
|
PrintHttpRequest( phreq,
|
|||
|
GET_CPP_VAR_PTR( HTTP_REQUEST, hreq),
|
|||
|
verbosity);
|
|||
|
} // PrintHttpRequestThunk()
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
PrintHttpRequest( HTTP_REQUEST * phreqOriginal,
|
|||
|
HTTP_REQUEST * phreq,
|
|||
|
CHAR Verbosity )
|
|||
|
/*++
|
|||
|
Description:
|
|||
|
This function takes the HTTP_REQUEST object and prints out
|
|||
|
the details for the same in the debugger. The granularity of the
|
|||
|
deatils are controlled by the verbosity flag
|
|||
|
|
|||
|
Arguments:
|
|||
|
phreqOriginal - pointer to the location where the original HTTP_REQUEST
|
|||
|
object is located.
|
|||
|
Note: phreqOriginal points to object inside debuggee process
|
|||
|
phreq - pointer to the HTTP_REQUEST object that is a copy
|
|||
|
of the contents located at [phreqOriginal]
|
|||
|
Note: phreq points to object inside the debugger process
|
|||
|
Verbostiy - level of details requested.
|
|||
|
|
|||
|
Returns:
|
|||
|
None
|
|||
|
--*/
|
|||
|
{
|
|||
|
if ( Verbosity >= '0') {
|
|||
|
|
|||
|
//
|
|||
|
// print Brief information about the client connection
|
|||
|
//
|
|||
|
|
|||
|
dprintf( "HTTP_REQUEST:%08p State = %15s\n"
|
|||
|
"\t CLIENT_CONN = %08p WamReq = %08p\n"
|
|||
|
,
|
|||
|
phreqOriginal,
|
|||
|
LookupHREQState( phreq->_htrState),
|
|||
|
phreq->_pClientConn,
|
|||
|
phreq->_pWamRequest
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
if ( Verbosity >= '1' ) {
|
|||
|
|
|||
|
//
|
|||
|
// Print all details for the Client Connection object
|
|||
|
//
|
|||
|
|
|||
|
dprintf( "\t _fKeepConn = %8s _fLoggedOn = %8s\n"
|
|||
|
"\t _fChunked = %8s Client Ver = %d.%d\n"
|
|||
|
"\t _tcpauth = %08p _Filter = %p \n"
|
|||
|
"\t _cbClientRequest = %8d _cbOldData = %8d\n"
|
|||
|
"\t _cbEntityBody = %8d _cbTotalEntBody = %8d\n"
|
|||
|
"\t _cbChunkHeader = %8d _cbChunkBytesRead=%8d\n"
|
|||
|
"\t _cbExtraData = %8d _pchExtraData = %08p\n"
|
|||
|
"\t _pMetaData = %08p _pURIInfo = %08p\n"
|
|||
|
"\t _pGetFile = %08p _Exec = %08p\n"
|
|||
|
"\t _pW3Stats = %08p\n"
|
|||
|
"\t _dwLogHttpResponse= %8d _dwLogWinError = %8d\n"
|
|||
|
,
|
|||
|
BoolValue(phreq->_fKeepConn),
|
|||
|
BoolValue(phreq->_fLoggedOn),
|
|||
|
BoolValue(phreq->_fChunked),
|
|||
|
(int) phreq->_VersionMajor, (int) phreq->_VersionMinor,
|
|||
|
(BYTE *) phreqOriginal + ((BYTE *) &phreq->_tcpauth - (BYTE *) phreq),
|
|||
|
(BYTE *) phreqOriginal + ((BYTE *) &phreq->_Filter - (BYTE *) phreq),
|
|||
|
phreq->_cbClientRequest,
|
|||
|
phreq->_cbOldData,
|
|||
|
phreq->_cbEntityBody,
|
|||
|
phreq->_cbTotalEntityBody,
|
|||
|
phreq->_cbChunkHeader,
|
|||
|
phreq->_cbChunkBytesRead,
|
|||
|
phreq->_cbExtraData,
|
|||
|
phreq->_pchExtraData,
|
|||
|
phreq->_pMetaData,
|
|||
|
phreq->_pURIInfo,
|
|||
|
phreq->_pGetFile,
|
|||
|
(BYTE *) phreqOriginal + ((BYTE *) &phreq->_Exec - (BYTE *) phreq),
|
|||
|
phreq->_pW3Stats,
|
|||
|
phreq->_dwLogHttpResponse,
|
|||
|
phreq->_dwLogWinError
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if ( Verbosity >= '2' ) {
|
|||
|
|
|||
|
//
|
|||
|
// Print state specific data
|
|||
|
//
|
|||
|
|
|||
|
dprintf( "\t _putstate = %8s _pFileNameLock = %8p\n"
|
|||
|
, LookupHreqPutState( phreq->_putstate)
|
|||
|
, phreq->_pFileNameLock
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
} // PrintHttpRequest()
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
PrintW3Statistics( W3_SERVER_STATISTICS * pw3statsDebuggee );
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
NAME: wstats
|
|||
|
|
|||
|
SYNOPSIS: Displays the w3svc statistics.
|
|||
|
By default print the global w3svc statistics.
|
|||
|
If given an argument treat that argument as a pointer to the
|
|||
|
W3_SERVER_STATISITCS structure and print it out
|
|||
|
|
|||
|
--*/
|
|||
|
DECLARE_API( wstats )
|
|||
|
{
|
|||
|
W3_SERVER_STATISTICS * pw3stats;
|
|||
|
W3_IIS_SERVICE * pw3s;
|
|||
|
|
|||
|
INIT_API();
|
|||
|
|
|||
|
while (*lpArgumentString == ' ')
|
|||
|
lpArgumentString++;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Capture the statistics.
|
|||
|
//
|
|||
|
if ( !*lpArgumentString ) {
|
|||
|
|
|||
|
dprintf( "OffsetOfGlobalStats from W3_IIS_SERVICE = %d (0x%x)\n",
|
|||
|
FIELD_OFFSET( W3_IIS_SERVICE, m_GlobalStats),
|
|||
|
FIELD_OFFSET( W3_IIS_SERVICE, m_GlobalStats)
|
|||
|
);
|
|||
|
|
|||
|
dprintf( "OffsetOfStats from W3_SERVER_INSTANCE = %d (0x%x)\n",
|
|||
|
FIELD_OFFSET( W3_SERVER_INSTANCE, m_pW3Stats),
|
|||
|
FIELD_OFFSET( W3_SERVER_INSTANCE, m_pW3Stats)
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// In IIS 4.0, the global statistics structure is part of
|
|||
|
// the W3_IIS_SERVICE structure - obtain the address indirectly.
|
|||
|
//
|
|||
|
|
|||
|
W3_IIS_SERVICE ** ppw3s;
|
|||
|
|
|||
|
ppw3s = (W3_IIS_SERVICE **) GetExpression( "w3svc!g_pInetSvc");
|
|||
|
if ( !ppw3s) {
|
|||
|
dprintf( "Unable to get w3svc!g_pInetSvc to fetch global stats\n");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// From the pointer to pointer to W3_IIS_SERVICE,
|
|||
|
// obtain the pointer to the W3_IIS_SERVICE
|
|||
|
//
|
|||
|
moveBlock( pw3s, ppw3s, sizeof(W3_IIS_SERVICE * ));
|
|||
|
|
|||
|
pw3stats = &pw3s->m_GlobalStats;
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// extract the address from the argument given
|
|||
|
//
|
|||
|
|
|||
|
pw3stats = (W3_SERVER_STATISTICS * ) GetExpression( lpArgumentString );
|
|||
|
}
|
|||
|
|
|||
|
PrintW3Statistics( pw3stats);
|
|||
|
return;
|
|||
|
} // stats
|
|||
|
|
|||
|
|
|||
|
# define P2DWORDS( a, b) \
|
|||
|
Print2Dwords( #a, \
|
|||
|
pw3statsDebugger->m_W3Stats. ## a, \
|
|||
|
#b, \
|
|||
|
pw3statsDebugger->m_W3Stats. ## b \
|
|||
|
)
|
|||
|
|
|||
|
VOID
|
|||
|
PrintW3Statistics( W3_SERVER_STATISTICS * pw3statsDebuggee )
|
|||
|
/*++
|
|||
|
Description:
|
|||
|
This function takes the W3_SERVER_STATISTICS object and prints out
|
|||
|
the details for the same in the debugger.
|
|||
|
|
|||
|
Arguments:
|
|||
|
pw3statsDebuggee - pointer to the location where the original structure
|
|||
|
is found inside the debuggee process.
|
|||
|
pw3statsDebugger - pointer to the copy of the data in the debugger process.
|
|||
|
|
|||
|
Returns:
|
|||
|
None
|
|||
|
--*/
|
|||
|
{
|
|||
|
DEFINE_CPP_VAR( W3_SERVER_STATISTICS, w3stats);
|
|||
|
W3_SERVER_STATISTICS * pw3statsDebugger =
|
|||
|
(W3_SERVER_STATISTICS *) &w3stats;
|
|||
|
|
|||
|
CHAR szLargeInt[64];
|
|||
|
|
|||
|
//
|
|||
|
// copy the statistics data into the local buffer inside the debugger
|
|||
|
// process so we can play with it
|
|||
|
//
|
|||
|
|
|||
|
move( w3stats, pw3statsDebuggee);
|
|||
|
|
|||
|
dprintf( " %30s = 0x%08p\n",
|
|||
|
"W3_SERVER_STATISTICS",
|
|||
|
pw3statsDebuggee);
|
|||
|
|
|||
|
PrintLargeInteger( "TotalBytesSent",
|
|||
|
&pw3statsDebugger->m_W3Stats.TotalBytesSent);
|
|||
|
PrintLargeInteger( "TotalBytesReceived",
|
|||
|
&pw3statsDebugger->m_W3Stats.TotalBytesReceived);
|
|||
|
|
|||
|
P2DWORDS( TotalFilesSent, TotalFilesReceived);
|
|||
|
dprintf("\n");
|
|||
|
|
|||
|
P2DWORDS( CurrentAnonymousUsers, CurrentNonAnonymousUsers);
|
|||
|
P2DWORDS( TotalAnonymousUsers, TotalNonAnonymousUsers);
|
|||
|
P2DWORDS( MaxAnonymousUsers, MaxNonAnonymousUsers);
|
|||
|
P2DWORDS( CurrentConnections, MaxConnections);
|
|||
|
P2DWORDS( ConnectionAttempts, LogonAttempts);
|
|||
|
dprintf( "\n");
|
|||
|
|
|||
|
P2DWORDS( TotalGets, TotalPosts);
|
|||
|
P2DWORDS( TotalHeads, TotalPuts);
|
|||
|
P2DWORDS( TotalDeletes, TotalTraces);
|
|||
|
P2DWORDS( TotalOthers, TotalNotFoundErrors);
|
|||
|
P2DWORDS( TotalCGIRequests, TotalBGIRequests);
|
|||
|
dprintf( "\n");
|
|||
|
|
|||
|
P2DWORDS( CurrentCGIRequests, MaxCGIRequests);
|
|||
|
P2DWORDS( CurrentBGIRequests, MaxBGIRequests);
|
|||
|
|
|||
|
|
|||
|
return;
|
|||
|
} // PrintW3Statistics()
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|