diff options
Diffstat (limited to 'private/nw/nw16/dll/debug.c')
-rw-r--r-- | private/nw/nw16/dll/debug.c | 584 |
1 files changed, 584 insertions, 0 deletions
diff --git a/private/nw/nw16/dll/debug.c b/private/nw/nw16/dll/debug.c new file mode 100644 index 000000000..886acd75d --- /dev/null +++ b/private/nw/nw16/dll/debug.c @@ -0,0 +1,584 @@ +/*++ + +Copyright (c) 1991-3 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: + +--*/ + +#include "procs.h" + +#if NWDBG + +// +// Set DebugControl to 1 to open the logfile on the first NW call and close it +// on process exit. +// + +int DebugCtrl = 0; + +BOOL UseConsole = FALSE; +BOOL UseLogFile = FALSE; +BOOL Verbose = FALSE; + +HANDLE LogFile = INVALID_HANDLE_VALUE; +#define LOGNAME (LPTSTR) TEXT("c:\\nwapi16.log") + +LONG NwMaxDump = SERVERNAME_LENGTH * MC; //128; + +#define ERR_BUF_SIZE 260 +#define NAME_BUF_SIZE 260 + +extern UCHAR CpuInProtectMode; + +LPSTR +ConvertFlagsToString( + IN WORD FlagsRegister, + OUT LPSTR Buffer + ); + +WORD +GetFlags( + VOID + ); + +VOID +HexDumpLine( + PCHAR pch, + ULONG len, + PCHAR s, + PCHAR t + ); + +VOID +DebugControl( + int Command + ) +/*++ + +Routine Description: + + This routine controls what we output as debug information and where. + +Arguments: + + IN int Command + +Return Value: + + none. + +--*/ +{ + + switch (Command) { + case 0: + UseLogFile = TRUE; + break; + + case 1: + UseConsole = TRUE; + break; + + case 2: + if (LogFile != INVALID_HANDLE_VALUE) { + CloseHandle(LogFile); + LogFile = INVALID_HANDLE_VALUE; + } + UseLogFile = FALSE; + UseConsole = FALSE; + break; + + case 8: + Verbose = TRUE; // Same as 4 only chatty + DebugCtrl = 4; + + case 4: + UseLogFile = TRUE; + break; + + } + NwPrint(("DebugControl %x\n", Command )); +} + +VOID +NwPrintf( + 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[200]; + int length; + + if (( UseConsole == FALSE ) && + ( UseLogFile == FALSE )) { + return; + } + + + va_start( arglist, Format ); + + length = _vsnprintf( OutputBuffer, sizeof(OutputBuffer)-1, Format, arglist ); + if (length < 0) { + return; + } + + OutputBuffer[sizeof(OutputBuffer)-1] = '\0'; // in-case length= 199; + + va_end( arglist ); + + if ( UseConsole ) { + DbgPrint( "%s", OutputBuffer ); + } else { + + if ( LogFile == INVALID_HANDLE_VALUE ) { + if ( UseLogFile ) { + LogFile = CreateFile( LOGNAME, + GENERIC_WRITE, + FILE_SHARE_WRITE | FILE_SHARE_READ, + NULL, + TRUNCATE_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL ); + + if (LogFile == INVALID_HANDLE_VALUE) { + LogFile = CreateFile( LOGNAME, + GENERIC_WRITE, + FILE_SHARE_WRITE | FILE_SHARE_READ, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL ); + } + + if ( LogFile == INVALID_HANDLE_VALUE ) { + UseLogFile = FALSE; + return; + } + } + } + + WriteFile( LogFile , (LPVOID )OutputBuffer, length, &length, NULL ); + } + +} // NwPrintf + +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 (( UseConsole == FALSE ) && + ( UseLogFile == FALSE )) { + return; + } + + if (( len > NwMaxDump ) || + ( len < 0 )) { + len = NwMaxDump; + } + + while (len) { + l = len < 16 ? len : 16; + + NwPrint(("%lx ", far_p)); + HexDumpLine (far_p, l, s, t); + NwPrint(("%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; + +} + + +VOID +DisplayExtendedError(VOID) +{ + TCHAR errorBuf[ERR_BUF_SIZE]; + TCHAR nameBuf[NAME_BUF_SIZE]; + DWORD errorCode; + DWORD status; + + status = WNetGetLastError( + &errorCode, + errorBuf, + ERR_BUF_SIZE, + nameBuf, + NAME_BUF_SIZE); + + if(status != WN_SUCCESS) { + NwPrint(("nwapi32: WNetGetLastError failed %d\n",status)); + return; + } + NwPrint(("nwapi32: EXTENDED ERROR INFORMATION: (from GetLastError)\n")); + NwPrint(("nwapi32: Code: %d\n",errorCode)); + NwPrint(("nwapi32: Description: "FORMAT_LPSTR"\n",errorBuf)); + NwPrint(("nwapi32: Provider: "FORMAT_LPSTR"\n\n",nameBuf)); + return; +} + +VOID +VrDumpRealMode16BitRegisters( + IN BOOL DebugStyle + ) + +/*++ + +Routine Description: + + Displays dump of 16-bit + real-mode 80286 registers - gp registers (8), segment registers (4), flags + register (1) instruction pointer register (1) + +Arguments: + + DebugStyle - determines look of output: + +DebugStyle == TRUE: + +ax=1111 bx=2222 cx=3333 dx=4444 sp=5555 bp=6666 si=7777 di=8888 +ds=aaaa es=bbbb ss=cccc cs=dddd ip=iiii fl fl fl fl fl fl fl fl + +DebugStyle == FALSE: + +cs:ip=cccc:iiii ss:sp=ssss:pppp bp=bbbb ax=1111 bx=2222 cx=3333 dx=4444 +ds:si=dddd:ssss es:di=eeee:dddd flags[ODIxSZxAxPxC]=fl fl fl fl fl fl fl fl + +Return Value: + + None. + +--*/ + +{ + char flags_string[25]; + + if (( UseConsole == FALSE ) && + ( UseLogFile == FALSE )) { + return; + } + + if (CpuInProtectMode) { + NwPrint(( "Protect Mode:\n")); + } + + if (DebugStyle) { + NwPrint(( + "ax=%04x bx=%04x cx=%04x dx=%04x sp=%04x bp=%04x si=%04x di=%04x\n" + "ds=%04x es=%04x ss=%04x cs=%04x ip=%04x %s\n\n", + + pNwDosTable->SavedAx, //getAX(), + getBX(), + getCX(), + getDX(), + getSP(), + getBP(), + getSI(), + getDI(), + getDS(), + getES(), + getSS(), + getCS(), + getIP(), + ConvertFlagsToString(GetFlags(), flags_string) + )); + } else { + NwPrint(( + "cs:ip=%04x:%04x ss:sp=%04x:%04x bp=%04x ax=%04x bx=%04x cx=%04x dx=%04x\n" + "ds:si=%04x:%04x es:di=%04x:%04x flags[ODITSZxAxPxC]=%s\n\n", + getCS(), + getIP(), + getSS(), + getSP(), + getBP(), + pNwDosTable->SavedAx, //getAX(), + getBX(), + getCX(), + getDX(), + getDS(), + getSI(), + getES(), + getDI(), + ConvertFlagsToString(GetFlags(), flags_string) + )); + } +} + +LPSTR +ConvertFlagsToString( + IN WORD FlagsRegister, + OUT LPSTR Buffer + ) + +/*++ + +Routine Description: + + Given a 16-bit word, interpret bit positions as for x86 Flags register + and produce descriptive string of flags state (as per debug) eg: + + NV UP DI PL NZ NA PO NC ODItSZxAxPxC = 000000000000b + OV DN EI NG ZR AC PE CY ODItSZxAxPxC = 111111111111b + + Trap Flag (t) is not dumped since this has no interest for programs which + are not debuggers or don't examine program execution (ie virtually none) + +Arguments: + + FlagsRegister - 16-bit flags + Buffer - place to store string. Requires 25 bytes inc \0 + +Return Value: + + Address of <Buffer> + +--*/ + +{ + static char* flags_states[16][2] = { + //0 1 + "NC", "CY", // CF (0x0001) - Carry + "", "", // x (0x0002) + "PO", "PE", // PF (0x0004) - Parity + "", "", // x (0x0008) + "NA", "AC", // AF (0x0010) - Aux (half) carry + "", "", // x (0x0020) + "NZ", "ZR", // ZF (0x0040) - Zero + "PL", "NG", // SF (0x0080) - Sign + "", "", // TF (0x0100) - Trap (not dumped) + "DI", "EI", // IF (0x0200) - Interrupt + "UP", "DN", // DF (0x0400) - Direction + "NV", "OV", // OF (0x0800) - Overflow + "", "", // x (0x1000) - (I/O Privilege Level) (not dumped) + "", "", // x (0x2000) - (I/O Privilege Level) (not dumped) + "", "", // x (0x4000) - (Nested Task) (not dumped) + "", "" // x (0x8000) + }; + int i; + WORD bit; + BOOL on; + + *Buffer = 0; + for (bit=0x0800, i=11; bit; bit >>= 1, --i) { + on = (BOOL)((FlagsRegister & bit) == bit); + if (flags_states[i][on][0]) { + strcat(Buffer, flags_states[i][on]); + strcat(Buffer, " "); + } + } + return Buffer; +} + +WORD +GetFlags( + VOID + ) + +/*++ + +Routine Description: + + Supplies the missing softpc function + +Arguments: + + None. + +Return Value: + + Conglomerates softpc flags into x86 flags word + +--*/ + +{ + WORD flags; + + flags = (WORD)getCF(); + flags |= (WORD)getPF() << 2; + flags |= (WORD)getAF() << 4; + flags |= (WORD)getZF() << 6; + flags |= (WORD)getSF() << 7; + flags |= (WORD)getIF() << 9; + flags |= (WORD)getDF() << 10; + flags |= (WORD)getOF() << 11; + + return flags; +} + +VOID +VrDumpNwData( + VOID + ) + +/*++ + +Routine Description: + + Dumps out the state of the 16 bit datastructures. + +Arguments: + + none. + +Return Value: + + None. + +--*/ + +{ + int index; + int Drive; + + if (Verbose == FALSE) { + return; + } + + NwPrint(( "Preferred = %x, Primary = %x\n", + pNwDosTable->PreferredServer, + pNwDosTable->PrimaryServer)); + + for (index = 0; index < MC; index++) { + + + if ((PUCHAR)pNwDosTable->ServerNameTable[index][0] != 0 ) { + + if (pNwDosTable->ConnectionIdTable[index].ci_InUse != IN_USE) { + NwPrint(("Warning Connection not in use %x: %x\n", + index, + pNwDosTable->ConnectionIdTable[index].ci_InUse)); + } + + NwPrint((" Server %d = %s, Connection = %d\n", + index, + (PUCHAR)pNwDosTable-> ServerNameTable[index], + (((pNwDosTable->ConnectionIdTable[index]).ci_ConnectionHi * 256) + + ( pNwDosTable-> ConnectionIdTable[index]).ci_ConnectionLo ))); + } else { + if (pNwDosTable->ConnectionIdTable[index].ci_InUse != FREE) { + NwPrint(("Warning Connection in use but name is null %x: %x\n", + index, + pNwDosTable->ConnectionIdTable[index])); + } + } + } + + for (Drive = 0; Drive < MD; Drive++ ) { + + + if (pNwDosTable->DriveFlagTable[Drive] & 3) { + NwPrint(("%c=%x on server %d,",'A' + Drive, + pNwDosTable->DriveFlagTable[Drive], + pNwDosTable->DriveIdTable[ Drive ] )); + } + + } + NwPrint(("\n")); +} +#endif + |