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.8 KiB
370 lines
8.8 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
|
|
|
|
|