/*----------------------------------------------------------------------------- * Copyright (C) Microsoft Corporation, 1995 - 1996. * All rights reserved. * * Snipped from SChannel sources * * 1/23/96 *----------------------------------------------------------------------------*/ #include #include #include #include #include DWORD g_dwEventLogging=0; typedef LONG HRESULT; #include "pstdef.h" /*----------------------------------------------------------------------------*/ /* NOTE: This file not compiled for retail builds */ /*----------------------------------------------------------------------------*/ #if DBG #ifdef HEAPDUMP #include #endif #define WINDEBUG #ifndef min #define min(x,y) ((x)<(y)?(x):(y)) #endif DWORD g_dwInfoLevel = SS_LOG_WARNING | SS_LOG_ERROR; DWORD SSTraceIndent = 0; #define MAX_DEBUG_BUFFER 2048 // This function simply outputs information to the debugging log file handle. void SSDebugOutput(char *szOutString) { OutputDebugStringA(szOutString); } void DbgDumpHexString(const unsigned char *String, DWORD cbString) { unsigned int i; for (i = 0; i < cbString; i++) { int j; char *pch; char ach[9]; pch = &ach[wsprintf(ach, "%2.2x", String[i])]; SS_ASSERT(pch - ach <= sizeof(ach) - 4); if ((i & 1) == 1) { *pch++ = ' '; } if ((i & 7) == 7) { *pch++ = ' '; } if ((i & 15) == 15) { *pch++ = '\n'; } *pch = '\0'; SSDebugOutput(ach); } } char *aszSSDebugLevel[] = { "Error ", "Warning", "Trace ", "Mem ", "Result " }; void SSDebugLog(long Mask, const char *Format, ...) { va_list ArgList; int Level = 0; int PrefixSize = 0; int iOut; char szOutString[MAX_DEBUG_BUFFER]; long OriginalMask = Mask; if (Mask & g_dwInfoLevel) { while (!(Mask & 1)) { Level++; Mask >>= 1; } if (Level >= sizeof(aszSSDebugLevel) / sizeof(char *)) { Level = sizeof(aszSSDebugLevel) / sizeof(char *) - 1; } // Make the prefix first: "Process.Thread> GINA-XXX" iOut = wsprintf( szOutString, "%3d.%3d> %s: ", GetCurrentProcessId(), GetCurrentThreadId(), aszSSDebugLevel[Level]); PrefixSize = min(60, SSTraceIndent * 3); FillMemory(szOutString+iOut, PrefixSize, ' '); PrefixSize += iOut; szOutString[PrefixSize] = '\0'; va_start(ArgList, Format); if (wvsprintf(&szOutString[PrefixSize], Format, ArgList) < 0) { static char szOverFlow[] = "\n<256 byte OVERFLOW!>\n"; // Less than zero indicates that the string would not fit into the // buffer. Output a special message indicating overflow. lstrcpy( &szOutString[sizeof(szOutString) - sizeof(szOverFlow)], szOverFlow); } va_end(ArgList); SSDebugOutput(szOutString); } } LPSTR SzErrorCase(long err) { char *szName = "Unknown"; switch(err) { case PST_E_OK: szName = "PST_OK"; break; case PST_E_FAIL: szName = "PST_FAIL"; break; case PST_E_PROV_DLL_NOT_FOUND: szName = "PST_PROV_DLL_NOT_FOUND"; break; case PST_E_INVALID_HANDLE: szName = "PST_INVALID_HANDLE"; break; case PST_E_TYPE_EXISTS: szName = "PST_TYPE_EXISTS"; break; case PST_E_TYPE_NO_EXISTS: szName = "PST_TYPE_NO_EXISTS"; break; case PST_E_INVALID_RULESET: szName = "PST_INVALID_RULESET"; break; case PST_E_NO_PERMISSIONS: szName = "PST_NO_PERMISSIONS"; break; case PST_E_STORAGE_ERROR: szName = "PST_STORAGE_ERROR"; break; case PST_E_CALLER_NOT_VERIFIED: szName = "PST_CALLER_NOT_VERIFIED"; break; case PST_E_WRONG_PASSWORD: szName = "PST_WRONG_PASSWORD"; break; case PST_E_DISK_IMAGE_MISMATCH: szName = "PST_DISK_IMAGE_MISMATCH"; break; case PST_E_MEMORY_IMAGE_MISMATCH: szName = "PST_MEMORY_IMAGE_MISMATCH"; break; case PST_E_UNKNOWN_EXCEPTION: szName = "PST_UNKNOWN_EXCEPTION"; break; case PST_E_NYI: szName = "PST_NYI"; break; } return szName; } long SSLogErrorCode( long err, const char *szFile, long lLine) { LPSTR szName; szName = SzErrorCase(err); SSDebugLog(SS_LOG_RES, "Result: %s (0x%lx) - %s, Line %d\n", szName, err, szFile, lLine); return err; } #pragma warning(disable:4206) /* Disable the empty translation unit */ /* warning/error */ void SSAssert( void * FailedAssertion, void * FileName, unsigned long LineNumber, char * Message) { SSDebugLog(SS_LOG_ERROR, "Assertion FAILED, %s, %s : %d\n", FailedAssertion, FileName, LineNumber); DebugBreak(); } // NOTE: heap dumping reqs winbasep.h, generated by // windows build. Therefore, heap dumping unsupported // in this build. // Get winbasep.h and define HEAPDUMP to dump heap. int HeapFlags = 0x0; // no trace //int HeapFlags = 0x2; // output window trace VOID DumpHeapState(char *pszMsg) { #ifdef HEAPDUMP DWORD dwWritten; char szOutString[256]; if (HeapFlags & 2) { HANDLE BaseHeap = RtlProcessHeap(); HEAP_SUMMARY HeapSum; wsprintf(szOutString, "%s: HeapSummary(%p): ", pszMsg, BaseHeap); HeapSum.cb = sizeof(HeapSum); if (!HeapSummary(BaseHeap, 0, &HeapSum)) { wsprintf( &szOutString[lstrlen(szOutString)], "FAILED: %u\n", GetLastError()); } else { wsprintf( &szOutString[lstrlen(szOutString)], "Allocated=%x Committed=%x\n", HeapSum.cbAllocated, HeapSum.cbCommitted); } SSDebugOutput(szOutString); } #endif // HEAPDUMP } VOID CaptureStackBackTrace( EXCEPTION_POINTERS *pep, ULONG cSkip, ULONG cFrames, ULONG *aeip) { FillMemory(aeip, cFrames * sizeof(aeip[0]), 0); #if i386 == 1 { ULONG ieip, *pebp; ULONG *pebpMax; ULONG *pebpMin; if (pep == NULL) { ieip = 0; cSkip++; // always skip current frame pebp = ((ULONG *) &pep) - 2; } else { ieip = 1; SS_ASSERT(cSkip == 0); aeip[0] = pep->ContextRecord->Eip; pebp = (ULONG *) pep->ContextRecord->Ebp; } pebpMin = (ULONG *) &pep - 3; // start below current frame pebpMax = pebpMin + 16*1024/sizeof(ULONG); if (pebp >= pebpMin && pebp < pebpMax) { // __try { for ( ; ieip < cSkip + cFrames; ieip++) { ULONG *pebpNext; if (ieip >= cSkip) { aeip[ieip - cSkip] = *(pebp + 1); // save an eip } pebpNext = (ULONG *) *pebp; if (pebpNext < pebp + 2 || pebpNext >= pebpMax - 1) { break; } pebp = pebpNext; } } // __except(EXCEPTION_EXECUTE_HANDLER) { } } } #endif // i386 == 1 } //////////////////////////////////////////////////////// // debug mem routines #define CMEMMAX 500 #define CEIP 6 int cMemAlloc; int cMemAlloc2; ULONG cbMemTotal; ULONG cbMemTotal2; typedef struct _MEM { VOID *pv; ULONG cb; ULONG aeip[CEIP]; } MEM; MEM amem[CMEMMAX]; VOID * SSAlloc(DWORD cb) { VOID *pv; int i; char szOutString[256]; int iRecorded = -1; MEM mem; DumpHeapState("Before Alloc"); if (HeapFlags & 2) { CaptureStackBackTrace(NULL, 1, CEIP, mem.aeip); wsprintf(szOutString, "AllocMem(%x bytes): ", cb); cMemAlloc2++; cbMemTotal2 += cb; mem.cb = cb; } pv = LocalAlloc(LMEM_FIXED, cb); if (HeapFlags & 2) { mem.pv = pv; if (pv != NULL) { for (i = 0; i < CMEMMAX; i++) { if (amem[i].pv == pv) { char szOutString2[256]; wsprintf( szOutString2, "FreeDup(%p) (%x bytes) from %x %x %x %x %x %x (%d)\n", pv, amem[i].cb, amem[i].aeip[0], amem[i].aeip[1], amem[i].aeip[2], amem[i].aeip[3], amem[i].aeip[4], amem[i].aeip[5], i); SSDebugOutput(szOutString2); cMemAlloc--; cbMemTotal -= amem[i].cb; amem[i].pv = NULL; } if (amem[i].pv == NULL && iRecorded == -1) { amem[i] = mem; cMemAlloc++; cbMemTotal += cb; iRecorded = i; } } } else { lstrcat(szOutString, "FAILED: "); } wsprintf( &szOutString[lstrlen(szOutString)], "0x%p from %x %x %x %x %x %x (%d)\n", mem.pv, mem.aeip[0], mem.aeip[1], mem.aeip[2], mem.aeip[3], mem.aeip[4], mem.aeip[5], iRecorded); SSDebugOutput(szOutString); } DumpHeapState("After Alloc"); return(pv); } VOID * SSReAlloc(VOID *pv, DWORD cb) { void* pTemp; pTemp = LocalReAlloc(pv, cb, LMEM_MOVEABLE); // allow realloc to move this memory if (pTemp == NULL) { CHAR sz[50]; wsprintf(sz, "ReAlloc Failed! error %d\n", GetLastError()); SSDebugOutput(sz); } else { if (pv != pTemp) SSDebugOutput("Performance: ReAlloc forced to move memory!\n"); } return pTemp; } VOID SSFree(VOID *pv) { int i; char szOutString[256]; DumpHeapState("Before Free"); if (HeapFlags & 2) { cMemAlloc2--; wsprintf(szOutString, "FreeMem(%p)", pv); for (i = 0; i < CMEMMAX; i++) { if (pv == amem[i].pv) { cMemAlloc--; cbMemTotal -= amem[i].cb; amem[i].pv = NULL; wsprintf( &szOutString[lstrlen(szOutString)], " (%x bytes) from %x %x %x %x %x %x (%d)", amem[i].cb, amem[i].aeip[0], amem[i].aeip[1], amem[i].aeip[2], amem[i].aeip[3], amem[i].aeip[4], amem[i].aeip[5], i); break; } } } LocalFree(pv); if (HeapFlags & 2) { lstrcat(szOutString, "\n"); SSDebugOutput(szOutString); } DumpHeapState("After Free"); } SIZE_T SSSize(HLOCAL hMem) { return LocalSize( hMem ); } #endif /* DBG */ /*----------------------------------------------------------------------------*/ /* NOTE: This file not compiled for retail builds */ /*----------------------------------------------------------------------------*/