/*++ Copyright (c) 1997 FORE Systems, Inc. Copyright (c) 1997 Microsoft Corporation Module Name: debug.c Abstract: This file contains debugging support. Author: Larry Cleeton, FORE Systems (v-lcleet@microsoft.com, lrc@fore.com) Environment: Kernel mode Revision History: --*/ #include "precomp.h" #include #include #pragma hdrstop #if DBG ULONG DbgVerbosity = 0; #if DBG_TRACE ULONG DbgLogSize = 128*1024; TRACELOG TraceLog; PUCHAR pTraceLogSpace; #endif #include "oidstrng.h" #include "irpstrng.h" #define MAX_HD_LENGTH 128 VOID DbgOut(ULONG Level, PUCHAR Message, ...) { char buf[DBG_OUTBUF_SIZE]; va_list ap; LONG numchars; if (Level > DbgVerbosity) return; va_start(ap, Message); numchars = _vsnprintf(buf, DBG_OUTBUF_SIZE, Message, ap); buf[DBG_OUTBUF_SIZE-1] = '\0'; DbgPrint("ATMLANE: %s", buf); } // // Careful! Uses static storage for string // PUCHAR UnicodeToString(PUNICODE_STRING unicodeString) { static CHAR ansiStringBuffer[129]; ANSI_STRING ansiString; ansiString.Length = 0; ansiString.MaximumLength = 128; ansiString.Buffer = ansiStringBuffer; if (unicodeString->Length > 0) { NdisUnicodeStringToAnsiString( &ansiString, unicodeString); } ansiStringBuffer[ansiString.Length] = '\0'; return ansiStringBuffer; } // // Careful! Uses static storage for string. // PUCHAR MacAddrToString(PVOID In) { static UCHAR String[20]; static PUCHAR HexChars = "0123456789abcdef"; PUCHAR EthAddr = (PUCHAR) In; UINT i; PUCHAR s; for (i = 0, s = String; i < 6; i++, EthAddr++) { *s++ = HexChars[(*EthAddr)>>4]; *s++ = HexChars[(*EthAddr)&0xf]; } *s = '\0'; return String; } // // Careful! Uses static storage for string. // PUCHAR AtmAddrToString(PVOID In) { static UCHAR String[80]; static PUCHAR HexChars = "0123456789abcdef"; PUCHAR AtmAddr = (PUCHAR) In; UINT i; PUCHAR s = String; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 1 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 2 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 3 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 4 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 5 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 6 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 7 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 8 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 9 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 10 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 11 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 12 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 13 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 14 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 15 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 16 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 17 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 18 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 19 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 20 *s = '\0'; return String; } PUCHAR OidToString(ULONG Oid) { struct _string_table *oidtab; for (oidtab = &oid_string_table[0]; oidtab->value != 0; oidtab++) if (oidtab->value == Oid) return oidtab->string; return oid_string_table[(sizeof(oid_string_table) / sizeof(struct _string_table)) - 1].string; } PUCHAR IrpToString(ULONG Irp) { struct _string_table *irptab; for (irptab = &irp_string_table[0]; irptab->value != 0xffffffff; irptab++) if (irptab->value == Irp) return irptab->string; return irp_string_table[(sizeof(irp_string_table) / sizeof(struct _string_table)) - 1].string; } VOID DbgPrintHexDump( IN ULONG Level, IN PUCHAR pBuffer, IN ULONG Length ) /*++ Routine Description: Print a hex dump of the given contiguous buffer. If the length is too long, we truncate it. Arguments: pBuffer - Points to start of data to be dumped Length - Length of above. Return Value: None --*/ { ULONG i; if (Level > DbgVerbosity) return; if (Length > MAX_HD_LENGTH) { Length = MAX_HD_LENGTH; } for (i = 0; i < Length; i++) { // // Check if we are at the end of a line // if ((i > 0) && ((i & 0xf) == 0)) { DbgPrint("\n"); } // // Print addr if we are at start of a new line // if ((i & 0xf) == 0) { DbgPrint("%08x ", pBuffer); } DbgPrint(" %02x", *pBuffer++); } // // Terminate the last line. // if (Length > 0) { DbgPrint("\n"); } } VOID TraceLogWritePkt( IN PTRACELOG pTraceLog, IN PNDIS_PACKET pNdisPacket ) { PNDIS_BUFFER pBuffer[5] = {(PNDIS_BUFFER)NULL}; do { pBuffer[0] = pNdisPacket->Private.Head; if (pBuffer[0] == (PNDIS_BUFFER)NULL) break; pBuffer[1] = pBuffer[0]->Next; if (pBuffer[1] == (PNDIS_BUFFER)NULL) break; pBuffer[2] = pBuffer[1]->Next; if (pBuffer[2] == (PNDIS_BUFFER)NULL) break; pBuffer[3] = pBuffer[2]->Next; if (pBuffer[3] == (PNDIS_BUFFER)NULL) break; pBuffer[4] = pBuffer[3]->Next; } while (FALSE); TraceLogWrite( pTraceLog, TL_NDISPACKET, pNdisPacket, pNdisPacket->Private.PhysicalCount, pNdisPacket->Private.TotalLength, pBuffer[0], pBuffer[1], pBuffer[2], pBuffer[3], pBuffer[4] ); } #endif #if DEBUG_SPIN_LOCK ULONG SpinLockInitDone = 0; NDIS_SPIN_LOCK LockLock; VOID AtmLaneAllocateSpinLock( IN PATMLANE_LOCK pLock, IN PUCHAR String, IN PUCHAR FileName, IN ULONG LineNumber ) { DBGP((2, "ALLOCATE LOCK %x %s\n", pLock, String)); if (SpinLockInitDone == 0) { SpinLockInitDone = 1; NdisAllocateSpinLock(&(LockLock)); } NdisAcquireSpinLock(&(LockLock)); pLock->Signature = ATMLANE_LOCK_SIG; NdisMoveMemory(pLock->TouchedByFileName, FileName, 32); pLock->TouchedByFileName[31] = 0x0; pLock->TouchedInLineNumber = LineNumber; pLock->IsAcquired = 0; pLock->OwnerThread = 0; NdisAllocateSpinLock(&(pLock->NdisLock)); NdisReleaseSpinLock(&(LockLock)); } VOID AtmLaneFreeSpinLock( IN PATMLANE_LOCK pLock, IN PUCHAR String, IN PUCHAR FileName, IN ULONG LineNumber ) { DBGP((2, "FREE LOCK %x %s\n", pLock, String)); NdisFreeSpinLock(pLock); } VOID AtmLaneAcquireSpinLock( IN PATMLANE_LOCK pLock, IN PUCHAR String, IN PUCHAR FileName, IN ULONG LineNumber ) { PKTHREAD pThread; DBGP((4, "ACQUIRE LOCK %x %s\n", pLock, String)); pThread = KeGetCurrentThread(); NdisAcquireSpinLock(&(LockLock)); if (pLock->Signature != ATMLANE_LOCK_SIG) { DbgPrint("Trying to acquire uninited lock %x, File %s, Line %d\n", pLock, FileName, LineNumber); DbgBreakPoint(); } if (pLock->IsAcquired != 0) { if (pLock->OwnerThread == pThread) { DbgPrint("Detected multiple locking!: pLock %x, File %s, Line %d\n", pLock, FileName, LineNumber); DbgPrint("pLock %x already acquired in File %s, Line %d\n", pLock, pLock->TouchedByFileName, pLock->TouchedInLineNumber); DbgBreakPoint(); } } // // Mark this lock. // pLock->IsAcquired++; NdisReleaseSpinLock(&(LockLock)); NdisAcquireSpinLock(&(pLock->NdisLock)); pLock->OwnerThread = pThread; NdisMoveMemory(pLock->TouchedByFileName, FileName, LOCK_FILE_NAME_LEN); pLock->TouchedByFileName[LOCK_FILE_NAME_LEN - 1] = 0x0; pLock->TouchedInLineNumber = LineNumber; } VOID AtmLaneReleaseSpinLock( IN PATMLANE_LOCK pLock, IN PUCHAR String, IN PUCHAR FileName, IN ULONG LineNumber ) { DBGP((4, "RELEASE LOCK %x %s\n", pLock, String)); NdisAcquireSpinLock(&(LockLock)); if (pLock->Signature != ATMLANE_LOCK_SIG) { DbgPrint("Trying to release uninited lock %x, File %s, Line %d\n", pLock, FileName, LineNumber); DbgBreakPoint(); } if (pLock->IsAcquired == 0) { DbgPrint("Detected release of unacquired lock %x, File %s, Line %d\n", pLock, FileName, LineNumber); DbgBreakPoint(); } NdisMoveMemory(pLock->TouchedByFileName, FileName, LOCK_FILE_NAME_LEN); pLock->TouchedByFileName[LOCK_FILE_NAME_LEN - 1] = 0x0; pLock->TouchedInLineNumber = LineNumber; pLock->IsAcquired--; pLock->OwnerThread = 0; NdisReleaseSpinLock(&(LockLock)); NdisReleaseSpinLock(&(pLock->NdisLock)); } #endif // DEBUG_SPIN_LOCK