windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/w3/debug/user.c
2020-09-26 16:20:57 +08:00

359 lines
9.2 KiB
C

/**********************************************************************/
/** Microsoft Windows NT **/
/** Copyright(c) Microsoft Corp., 1991 **/
/**********************************************************************/
/*
user.c
This module implements the "user" command of the W3 Server
debugger extension DLL.
The "user" command dumps the info pertaining to a specific user.
There is one parameter to this command. If this parameter is
positive, it is assumed to be the address of a USER_DATA structure
for a specific user. If the parameter is negative, its absolute
value is assumed to be a user ID. If no parameter is given, info
for all connected users is dumped.
FILE HISTORY:
KeithMo 13-Aug-1992 Created.
*/
#include "w3dbg.h"
//
// Private prototypes.
//
VOID DumpUserInfo( HANDLE hCurrentProcess,
USER_DATA * puser );
CHAR * InterpretState( USER_STATE state );
CHAR * InterpretXferType( XFER_TYPE xferType );
CHAR * InterpretXferMode( XFER_MODE xferMode );
VOID InterpretFlags( DWORD dwFlags );
/*******************************************************************
NAME: user
SYNOPSIS: Displays the info for a specific user.
ENTRY: hCurrentProcess - Handle to the current process.
hCurrentThread - Handle to the current thread.
dwCurrentPc - The current program counter
(EIP for x86, FIR for MIPS).
lpExtensionApis - Points to a structure containing
pointers to the debugger functions
that the command may invoke.
lpArgumentString - Points to any arguments passed
to the command.
NOTES: The argument string must contain either the address of
a USER_DATA structure (if positive) or a user ID (if
negative).
HISTORY:
KeithMo 13-Aug-1992 Created.
********************************************************************/
VOID user( HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
LPVOID lpExtensionApis,
LPSTR lpArgumentString )
{
LONG lParam;
USER_DATA user;
//
// Grab the debugger entrypoints.
//
GrabDebugApis( lpExtensionApis );
//
// Evaluate the parameter (if present).
//
if( ( lpArgumentString == NULL ) || ( *lpArgumentString == '\0' ) )
{
lParam = 0;
}
else
{
lParam = (LONG)DebugEval( lpArgumentString );
}
//
// Interpret the parameter.
//
if( lParam > 0 )
{
//
// User specified an address. Dump the user info
// at that address.
//
ReadProcessMemory( hCurrentProcess,
(LPVOID)lParam,
(LPVOID)&user,
sizeof(user),
(LPDWORD)NULL );
DumpUserInfo( hCurrentProcess, &user );
}
else
{
//
// User specified either nothing (0) or a user ID (< 0).
//
LIST_ENTRY list;
LIST_ENTRY * plist;
LIST_ENTRY * plistHead;
lParam = -lParam;
plistHead = (LIST_ENTRY *)DebugEval( "listUserData" );
ReadProcessMemory( hCurrentProcess,
(LPVOID)plistHead,
(LPVOID)&list,
sizeof(list),
(LPDWORD)NULL );
plist = list.Flink;
while( plist != plistHead )
{
ReadProcessMemory( hCurrentProcess,
(LPVOID)CONTAINING_RECORD( plist,
USER_DATA,
link ),
(LPVOID)&user,
sizeof(user),
(LPDWORD)NULL );
if( ( lParam == 0 ) || ( user.idUser == (DWORD)lParam ) )
{
DumpUserInfo( hCurrentProcess, &user );
if( lParam != 0 )
{
break;
}
}
plist = user.link.Flink;
//
// Check for CTRL-C, to let the user bag-out early.
//
if( DebugCheckCtrlC() )
{
break;
}
}
if( ( lParam != 0 ) && ( plist == plistHead ) )
{
DebugPrint( "user ID %ld not found\n", lParam );
}
}
} // user
VOID DumpUserInfo( HANDLE hCurrentProcess,
USER_DATA * puser )
{
char szDir[MAX_PATH];
int i;
DebugPrint( "user @ %08lX:\n", puser );
DebugPrint( " link.Flink = %08lX\n", puser->link.Flink );
DebugPrint( " link.Blink = %08lX\n", puser->link.Blink );
DebugPrint( " dwFlags = %08lX\n", puser->dwFlags );
InterpretFlags( puser->dwFlags );
DebugPrint( " sControl = %d\n", puser->sControl );
DebugPrint( " sData = %d\n", puser->sData );
DebugPrint( " hToken = %08lX\n", puser->hToken );
DebugPrint( " state = %s\n", InterpretState( puser->state ) );
DebugPrint( " idUser = %lu\n", puser->idUser );
DebugPrint( " tConnect = %08lX\n", puser->tConnect );
DebugPrint( " tAccess = %08lX\n", puser->tAccess );
DebugPrint( " xferType = %s\n", InterpretXferType( puser->xferType ) );
DebugPrint( " xferMode = %s\n", InterpretXferMode( puser->xferMode ) );
DebugPrint( " inetLocal = %s\n", inet_ntoa( puser->inetLocal ) );
DebugPrint( " inetHost = %s\n", inet_ntoa( puser->inetHost ) );
DebugPrint( " inetData = %s\n", inet_ntoa( puser->inetData ) );
DebugPrint( " portData = %u\n", puser->portData );
DebugPrint( " hDir = %08lX\n", puser->hDir );
DebugPrint( " pIoBuffer = %08lX\n", puser->pIoBuffer );
DebugPrint( " pszRename = %s\n", puser->pszRename );
for( i = 0 ; i < 26 ; i++ )
{
if( puser->apszDirs[i] != NULL )
{
ReadProcessMemory( hCurrentProcess,
puser->apszDirs[i],
szDir,
sizeof(szDir),
(LPDWORD)NULL );
DebugPrint( " dir %c: = %s\n", 'A'+i, szDir );
}
}
DebugPrint( " szDir = %s\n", puser->szDir );
DebugPrint( " szUser = %s\n", puser->szUser );
DebugPrint( " idThread = %lu\n", puser->idThread );
DebugPrint( "\n" );
} // DumpUserInfo
CHAR * InterpretState( USER_STATE state )
{
CHAR * pszResult = "unknown";
switch( state )
{
case Embryonic :
pszResult = "Embryonic";
break;
case WaitingForUser :
pszResult = "WaitingForUser";
break;
case WaitingForPass :
pszResult = "WaitingForPass";
break;
case LoggedOn :
pszResult = "LoggedOn";
break;
case Disconnected :
pszResult = "Disconnected";
break;
default :
break;
}
return pszResult;
} // InterpretState
CHAR * InterpretXferType( XFER_TYPE xferType )
{
CHAR * pszResult = "unknown";
switch( xferType )
{
case AsciiType :
pszResult = "ASCII";
break;
case BinaryType :
pszResult = "BINARY";
break;
default :
break;
}
return pszResult;
} // InterpretXferType
CHAR * InterpretXferMode( XFER_MODE xferMode )
{
CHAR * pszResult = "unknown";
switch( xferMode )
{
case StreamMode :
pszResult = "STREAM";
break;
case BlockMode :
pszResult = "BLOCK";
break;
default :
break;
}
return pszResult;
} // InterpretXferMode
typedef struct FLAG_MAP
{
DWORD flag;
CHAR * pszName;
} FLAG_MAP;
FLAG_MAP flag_map[] =
{
{ UF_MSDOS_DIR_OUTPUT, "UF_MSDOS_DIR_OUTPUT" },
{ UF_ANNOTATE_DIRS, "UF_ANNOTATE_DIRS" },
{ UF_READ_ACCESS, "UF_READ_ACCESS" },
{ UF_WRITE_ACCESS, "UF_WRITE_ACCESS" },
{ UF_OOB_ABORT, "UF_OOB_ABORT" },
{ UF_RENAME, "UF_RENAME" },
{ UF_PASSIVE, "UF_PASSIVE" },
{ UF_ANONYMOUS, "UF_ANONYMOUS" },
{ UF_TRANSFER, "UF_TRANSFER" },
{ UF_OOB_DATA, "UF_OOB_DATA" }
};
#define NUM_FLAG_MAP (sizeof(flag_map) / sizeof(flag_map[0]))
VOID InterpretFlags( DWORD dwFlags )
{
INT i;
FLAG_MAP * pmap = flag_map;
for( i = 0 ; i < NUM_FLAG_MAP ; i++ )
{
if( dwFlags & pmap->flag )
{
DebugPrint( " %s\n", pmap->pszName );
dwFlags &= ~pmap->flag;
}
pmap++;
}
if( dwFlags != 0 )
{
DebugPrint( " Remaining flags = %08lX\n", dwFlags );
}
} // InterpretFlags