diff options
Diffstat (limited to 'private/net/netbios/debug.c')
-rw-r--r-- | private/net/netbios/debug.c | 369 |
1 files changed, 369 insertions, 0 deletions
diff --git a/private/net/netbios/debug.c b/private/net/netbios/debug.c new file mode 100644 index 000000000..f6340b67c --- /dev/null +++ b/private/net/netbios/debug.c @@ -0,0 +1,369 @@ +/*++ + +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 + |