Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

370 lines
8.4 KiB

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
debug.c
Abstract:
This component of netbios runs in the user process and can ( when
built in a debug kernel) will log to either the console or through the
kernel debugger.
Author:
Colin Watson (ColinW) 24-Jun-91
Revision History:
--*/
#if DBG
#include <netb.h>
#include <stdarg.h>
#include <stdio.h>
ULONG NbDllDebug = 0x0;
#define NB_DLL_DEBUG_NCB 0x00000001 // print all NCB's submitted
#define NB_DLL_DEBUG_NCB_BUFF 0x00000002 // print buffers for NCB's submitted
BOOL UseConsole = FALSE;
BOOL UseLogFile = TRUE;
HANDLE LogFile = INVALID_HANDLE_VALUE;
#define LOGNAME (LPTSTR) TEXT("netbios.log")
LONG NbMaxDump = 128;
// Macro used in DisplayNcb
#define DISPLAY_COMMAND( cmd ) \
case cmd: NbPrintf(( #cmd )); break;
VOID
FormattedDump(
PCHAR far_p,
LONG len
);
VOID
HexDumpLine(
PCHAR pch,
ULONG len,
PCHAR s,
PCHAR t
);
VOID
DisplayNcb(
IN PNCBI pncbi
)
/*++
Routine Description:
This routine displays on the standard output stream the contents
of the Ncb.
Arguments:
IN PNCBI - Supplies the NCB to be displayed.
Return Value:
none.
--*/
{
if ( (NbDllDebug & NB_DLL_DEBUG_NCB) == 0 ) {
return;
}
NbPrintf(( "PNCB %#010lx\n", pncbi));
NbPrintf(( "ncb_command %#04x ", pncbi->ncb_command));
switch ( pncbi->ncb_command & ~ASYNCH ) {
DISPLAY_COMMAND( NCBCALL );
DISPLAY_COMMAND( NCBLISTEN );
DISPLAY_COMMAND( NCBHANGUP );
DISPLAY_COMMAND( NCBSEND );
DISPLAY_COMMAND( NCBRECV );
DISPLAY_COMMAND( NCBRECVANY );
DISPLAY_COMMAND( NCBCHAINSEND );
DISPLAY_COMMAND( NCBDGSEND );
DISPLAY_COMMAND( NCBDGRECV );
DISPLAY_COMMAND( NCBDGSENDBC );
DISPLAY_COMMAND( NCBDGRECVBC );
DISPLAY_COMMAND( NCBADDNAME );
DISPLAY_COMMAND( NCBDELNAME );
DISPLAY_COMMAND( NCBRESET );
DISPLAY_COMMAND( NCBASTAT );
DISPLAY_COMMAND( NCBSSTAT );
DISPLAY_COMMAND( NCBCANCEL );
DISPLAY_COMMAND( NCBADDGRNAME );
DISPLAY_COMMAND( NCBENUM );
DISPLAY_COMMAND( NCBUNLINK );
DISPLAY_COMMAND( NCBSENDNA );
DISPLAY_COMMAND( NCBCHAINSENDNA );
DISPLAY_COMMAND( NCBLANSTALERT );
DISPLAY_COMMAND( NCBFINDNAME );
// Extensions
DISPLAY_COMMAND( NCALLNIU );
DISPLAY_COMMAND( NCBQUICKADDNAME );
DISPLAY_COMMAND( NCBQUICKADDGRNAME );
DISPLAY_COMMAND( NCBACTION );
default: NbPrintf(( " Unknown type")); break;
}
if ( pncbi->ncb_command & ASYNCH ) {
NbPrintf(( " | ASYNCH"));
}
NbPrintf(( "\nncb_retcode %#04x\n", pncbi->ncb_retcode));
NbPrintf(( "ncb_lsn %#04x\n", pncbi->ncb_lsn));
NbPrintf(( "ncb_num %#04x\n", pncbi->ncb_num));
NbPrintf(( "ncb_buffer %#010lx\n",pncbi->ncb_buffer));
NbPrintf(( "ncb_length %#06x\n", pncbi->ncb_length));
NbPrintf(( "\nncb_callname and ncb->name\n"));
FormattedDump( pncbi->cu.ncb_callname, NCBNAMSZ );
FormattedDump( pncbi->ncb_name, NCBNAMSZ );
if (((pncbi->ncb_command & ~ASYNCH) == NCBCHAINSEND) ||
((pncbi->ncb_command & ~ASYNCH) == NCBCHAINSENDNA)) {
NbPrintf(( "ncb_length2 %#06x\n", pncbi->cu.ncb_chain.ncb_length2));
NbPrintf(( "ncb_buffer2 %#010lx\n",pncbi->cu.ncb_chain.ncb_buffer2));
}
NbPrintf(( "ncb_rto %#04x\n", pncbi->ncb_rto));
NbPrintf(( "ncb_sto %#04x\n", pncbi->ncb_sto));
NbPrintf(( "ncb_post %lx\n", pncbi->ncb_post));
NbPrintf(( "ncb_lana_num %#04x\n", pncbi->ncb_lana_num));
NbPrintf(( "ncb_cmd_cplt %#04x\n", pncbi->ncb_cmd_cplt));
NbPrintf(( "ncb_reserve\n"));
FormattedDump( ((PNCB)pncbi)->ncb_reserve, 14 );
NbPrintf(( "ncb_next\n"));
FormattedDump( (PCHAR)&pncbi->u.ncb_next, sizeof( LIST_ENTRY) );
NbPrintf(( "ncb_iosb\n"));
FormattedDump( (PCHAR)&pncbi->u.ncb_iosb, sizeof( IO_STATUS_BLOCK ) );
NbPrintf(( "ncb_event %#04x\n", pncbi->ncb_event));
if ( (NbDllDebug & NB_DLL_DEBUG_NCB_BUFF) == 0 ) {
NbPrintf(( "\n\n" ));
return;
}
switch ( pncbi->ncb_command & ~ASYNCH ) {
case NCBSEND:
case NCBCHAINSEND:
case NCBDGSEND:
case NCBSENDNA:
case NCBCHAINSENDNA:
if ( pncbi->ncb_retcode == NRC_PENDING ) {
//
// If pending then presumably we have not displayed the ncb
// before. After its been sent there isn't much point in displaying
// the buffer again.
//
NbPrintf(( "ncb_buffer contents:\n"));
FormattedDump( pncbi->ncb_buffer, pncbi->ncb_length );
}
break;
case NCBRECV:
case NCBRECVANY:
case NCBDGRECV:
case NCBDGSENDBC:
case NCBDGRECVBC:
case NCBENUM:
case NCBASTAT:
case NCBSSTAT:
case NCBFINDNAME:
if ( pncbi->ncb_retcode != NRC_PENDING ) {
// Buffer has been loaded with data
NbPrintf(( "ncb_buffer contents:\n"));
FormattedDump( pncbi->ncb_buffer, pncbi->ncb_length );
}
break;
case NCBCANCEL:
// Buffer has been loaded with the NCB to be cancelled
NbPrintf(( "ncb_buffer contents:\n"));
FormattedDump( pncbi->ncb_buffer, sizeof(NCB));
break;
}
NbPrintf(( "\n\n" ));
}
VOID
NbPrint(
char *Format,
...
)
/*++
Routine Description:
This routine is equivalent to printf with the output being directed to
stdout.
Arguments:
IN char *Format - Supplies string to be output and describes following
(optional) parameters.
Return Value:
none.
--*/
{
va_list arglist;
char OutputBuffer[1024];
ULONG length;
if ( NbDllDebug == 0 ) {
return;
}
va_start( arglist, Format );
vsprintf( OutputBuffer, Format, arglist );
va_end( arglist );
if ( UseConsole ) {
DbgPrint( "%s", OutputBuffer );
} else {
length = strlen( OutputBuffer );
if ( LogFile == INVALID_HANDLE_VALUE ) {
if ( UseLogFile ) {
LogFile = CreateFile( LOGNAME,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL );
if ( LogFile == INVALID_HANDLE_VALUE ) {
// Could not access logfile so use stdout instead
UseLogFile = FALSE;
LogFile = GetStdHandle(STD_OUTPUT_HANDLE);
}
} else {
// Use the applications stdout file.
LogFile = GetStdHandle(STD_OUTPUT_HANDLE);
}
}
WriteFile( LogFile , (LPVOID )OutputBuffer, length, &length, NULL );
}
} // NbPrint
void
FormattedDump(
PCHAR far_p,
LONG len
)
/*++
Routine Description:
This routine outputs a buffer in lines of text containing hex and
printable characters.
Arguments:
IN far_p - Supplies buffer to be displayed.
IN len - Supplies the length of the buffer in bytes.
Return Value:
none.
--*/
{
ULONG l;
char s[80], t[80];
if ( len > NbMaxDump ) {
len = NbMaxDump;
}
while (len) {
l = len < 16 ? len : 16;
NbPrintf (("%lx ", far_p));
HexDumpLine (far_p, l, s, t);
NbPrintf (("%s%.*s%s\n", s, 1 + ((16 - l) * 3), "", t));
len -= l;
far_p += l;
}
}
VOID
HexDumpLine(
PCHAR pch,
ULONG len,
PCHAR s,
PCHAR t
)
/*++
Routine Description:
This routine builds a line of text containing hex and printable characters.
Arguments:
IN pch - Supplies buffer to be displayed.
IN len - Supplies the length of the buffer in bytes.
IN s - Supplies the start of the buffer to be loaded with the string
of hex characters.
IN t - Supplies the start of the buffer to be loaded with the string
of printable ascii characters.
Return Value:
none.
--*/
{
static UCHAR rghex[] = "0123456789ABCDEF";
UCHAR c;
UCHAR *hex, *asc;
hex = s;
asc = t;
*(asc++) = '*';
while (len--) {
c = *(pch++);
*(hex++) = rghex [c >> 4] ;
*(hex++) = rghex [c & 0x0F];
*(hex++) = ' ';
*(asc++) = (c < ' ' || c > '~') ? (CHAR )'.' : c;
}
*(asc++) = '*';
*asc = 0;
*hex = 0;
}
#endif