//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1996 - 1999 // // File: debug.cpp // // Contents: Debug sub system APIs implementation // // // 03/20/96 kevinr wrote it // 04/17/96 kevinr added OSS init // 05-Sep-1997 pberkman added sub-system debug. // //---------------------------------------------------------------------------- #include #include #if DBG #include #include #include #include #include #include #include #include #include "pkicrit.h" #include "dbgdef.h" // set DEBUG_MASK=0x26 LPSTR pszDEBUG_MASK = "DEBUG_MASK"; #define DEBUG_MASK_DELAY_FREE_MEM _CRTDBG_DELAY_FREE_MEM_DF /* 0x02 */ #define DEBUG_MASK_CHECK_ALWAYS _CRTDBG_CHECK_ALWAYS_DF /* 0x04 */ #define DEBUG_MASK_LEAK_CHECK _CRTDBG_LEAK_CHECK_DF /* 0x20 */ #define DEBUG_MASK_MEM \ (DEBUG_MASK_DELAY_FREE_MEM | DEBUG_MASK_CHECK_ALWAYS | DEBUG_MASK_LEAK_CHECK) // from asn1code.h: // #define DEBUGPDU 0x02 /* produce tracing output */ // #define DEBUG_ERRORS 0x10 /* print decoder errors to output */ // set OSS_DEBUG_MASK=0x02 // set OSS_DEBUG_MASK=0x10 - only print decoder errors LPSTR pszOSS_DEBUG_MASK = "OSS_DEBUG_MASK"; // receives trace output LPSTR pszOSS_DEBUG_TRACEFILE = "OSS_DEBUG_TRACEFILE"; static char *pszDEBUG_PRINT_MASK = "DEBUG_PRINT_MASK"; static char *pszDefualtSSTag = "ISPU"; static DBG_SS_TAG sSSTags[] = __DBG_SS_TAGS; static CRITICAL_SECTION DbgCriticalSection; #define OSS_SET_DECODING_FLAGS_PROC_IDX 0 #define OSS_SET_ENCODING_FLAGS_PROC_IDX 1 #define OSS_OPEN_TRACE_FILE_PROC_IDX 2 #define OSS_PROC_CNT 3 static LPSTR rgpszOssProc[OSS_PROC_CNT] = { "ossSetDecodingFlags", "ossSetEncodingFlags", "ossOpenTraceFile" }; static void *rgpvOssProc[OSS_PROC_CNT]; static HMODULE hmsossDll = NULL; static BOOL fLoadedOss = FALSE; static void OssUnload() { if (hmsossDll) { FreeLibrary(hmsossDll); hmsossDll = NULL; } } static void OssLoad() { DWORD i; if (fLoadedOss) return; EnterCriticalSection(&DbgCriticalSection); if (fLoadedOss) goto LeaveReturn; if (NULL == (hmsossDll = LoadLibraryA("msoss.dll"))) goto msossLoadLibraryError; for (i = 0; i < OSS_PROC_CNT; i++) { if (NULL == (rgpvOssProc[i] = GetProcAddress( hmsossDll, rgpszOssProc[i]))) goto msossGetProcAddressError; } LeaveReturn: LeaveCriticalSection(&DbgCriticalSection); CommonReturn: fLoadedOss = TRUE; return; ErrorReturn: LeaveCriticalSection(&DbgCriticalSection); OssUnload(); goto CommonReturn; TRACE_ERROR(msossLoadLibraryError) TRACE_ERROR(msossGetProcAddressError) } typedef int (DLL_ENTRY* pfnossSetDecodingFlags)(struct ossGlobal *world, unsigned long flags); static int DLL_ENTRY ossSetDecodingFlags(struct ossGlobal *world, unsigned long flags) { if (hmsossDll) return ((pfnossSetDecodingFlags) rgpvOssProc[OSS_SET_DECODING_FLAGS_PROC_IDX])( world, flags); else return API_DLL_NOT_LINKED; } typedef int (DLL_ENTRY* pfnossSetEncodingFlags)(struct ossGlobal *world, unsigned long flags); static int DLL_ENTRY ossSetEncodingFlags(struct ossGlobal *world, unsigned long flags) { if (hmsossDll) return ((pfnossSetEncodingFlags) rgpvOssProc[OSS_SET_ENCODING_FLAGS_PROC_IDX])( world, flags); else return API_DLL_NOT_LINKED; } typedef int (DLL_ENTRY* pfnossOpenTraceFile)(struct ossGlobal *world, char *fileName); static int DLL_ENTRY ossOpenTraceFile(struct ossGlobal *world, char *fileName) { if (hmsossDll) return ((pfnossOpenTraceFile) rgpvOssProc[OSS_OPEN_TRACE_FILE_PROC_IDX])( world, fileName); else return API_DLL_NOT_LINKED; } // //+------------------------------------------------------------------------- // // Pithy stubs to create stdcall proc from cdecl // //-------------------------------------------------------------------------- void* _stdcall scMalloc( size_t size) { return malloc(size); } void* _stdcall scRealloc( void *memblock, size_t size) { return realloc(memblock, size); } void _stdcall scFree( void *memblock) { free(memblock); } //+------------------------------------------------------------------------- // // Function: DbgGetDebugFlags // // Synopsis: Get the debug flags. // // Returns: the debug flags // //-------------------------------------------------------------------------- int WINAPI DbgGetDebugFlags() { char *pszEnvVar; char *p; int iDebugFlags = 0; if (pszEnvVar = getenv( pszDEBUG_MASK)) iDebugFlags = strtol( pszEnvVar, &p, 16); return iDebugFlags; } //+------------------------------------------------------------------------- // // Function: DbgProcessAttach // // Synopsis: Handle process attach. // // Returns: TRUE // //-------------------------------------------------------------------------- BOOL WINAPI DbgProcessAttach() { int tmpFlag; #ifdef _DEBUG tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); // get current tmpFlag |= DbgGetDebugFlags(); // enable flags tmpFlag &= ~_CRTDBG_CHECK_CRT_DF; // disable CRT block checking _CrtSetDbgFlag( tmpFlag); // set new value #endif return TRUE; } //+------------------------------------------------------------------------- // // Function: DbgProcessDetach // // Synopsis: Handle process detach. // // Returns: TRUE // //-------------------------------------------------------------------------- BOOL WINAPI DbgProcessDetach() { return TRUE; } //+------------------------------------------------------------------------- // // Function: DbgInitOSS // // Synopsis: Do OSS init for debug. // // Returns: TRUE // // Note: Always FRONT_ALIGN encoding // //-------------------------------------------------------------------------- BOOL WINAPI DbgInitOSS( OssGlobal *pog) { char *pszEnvVar; char *p; __try { // Attempt to do delay, demand loading of msoss.dll OssLoad(); // from asn1code.h: // #define DEBUGPDU 0x02 /* produce tracing output */ // #define DEBUG_ERRORS 0x10 /* print decoder errors to output */ // set OSS_DEBUG_MASK=0x02 // set OSS_DEBUG_MASK=0x10 - only print decoder errors if (pszEnvVar = getenv( pszOSS_DEBUG_MASK)) { unsigned long ulEnvVar; ulEnvVar = strtoul( pszEnvVar, &p, 16) & (DEBUGPDU | DEBUG_ERRORS); if ( ulEnvVar) ossSetDecodingFlags( pog, ulEnvVar | RELAXBER); if ( DEBUGPDU & ulEnvVar) ossSetEncodingFlags( pog, DEBUGPDU | FRONT_ALIGN); else ossSetEncodingFlags( pog, FRONT_ALIGN); } else { ossSetDecodingFlags( pog, DEBUG_ERRORS | RELAXBER); ossSetEncodingFlags( pog, FRONT_ALIGN); } if (pszEnvVar = getenv( pszOSS_DEBUG_TRACEFILE)) ossOpenTraceFile( pog, pszEnvVar); #ifdef _DEBUG if (DbgGetDebugFlags() & DEBUG_MASK_MEM) { pog->mallocp = scMalloc; pog->reallocp = scRealloc; pog->freep = scFree; } #else pog->mallocp = scMalloc; pog->reallocp = scRealloc; pog->freep = scFree; #endif return TRUE; } __except(EXCEPTION_EXECUTE_HANDLER) { return FALSE; } } //+------------------------------------------------------------------------- // // Function: DebugDllMain // // Synopsis: Initialize the debug DLL // // Returns: TRUE // //-------------------------------------------------------------------------- BOOL WINAPI DebugDllMain( HMODULE hInst, ULONG ulReason, LPVOID lpReserved) { BOOL fRet = TRUE; switch (ulReason) { case DLL_PROCESS_ATTACH: fRet = DbgProcessAttach(); if (fRet) { fRet = Pki_InitializeCriticalSection(&DbgCriticalSection); if (!fRet) DbgProcessDetach(); } break; case DLL_PROCESS_DETACH: fRet = DbgProcessDetach(); OssUnload(); DeleteCriticalSection(&DbgCriticalSection); break; default: break; } return fRet; } const char *DbgGetSSString(DWORD dwSubSystemId) { DBG_SS_TAG *psSS; psSS = &sSSTags[0]; while (psSS->dwSS > 0) { if ((psSS->dwSS & dwSubSystemId) > 0) { if (psSS->pszTag) { return(psSS->pszTag); } return(pszDefualtSSTag); } psSS++; } return(pszDefualtSSTag); } static BOOL DbgIsSSActive(DWORD dwSSIn) { char *pszEnvVar; DWORD dwEnv; dwEnv = 0; if (pszEnvVar = getenv(pszDEBUG_PRINT_MASK)) { dwEnv = (DWORD)strtol(pszEnvVar, NULL, 16); } return((dwEnv & dwSSIn) > 0); } //+------------------------------------------------------------------------- // // Function: DbgPrintf // // Synopsis: outputs debug info to stdout and debugger // // Returns: number of chars output // //-------------------------------------------------------------------------- int WINAPIV DbgPrintf(DWORD dwSubSystemId, LPCSTR lpFmt, ...) { va_list arglist; CHAR ach1[1024]; CHAR ach2[1080]; int cch; HANDLE hStdOut; DWORD cb; DWORD dwErr; dwErr = GetLastError(); if (!(DbgIsSSActive(dwSubSystemId))) { SetLastError(dwErr); return(0); } _try { va_start(arglist, lpFmt); _vsnprintf( ach1, sizeof(ach1), lpFmt, arglist); va_end(arglist); cch = wsprintf(ach2,"%s: %s", DbgGetSSString(dwSubSystemId), ach1); hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); if (hStdOut != INVALID_HANDLE_VALUE) { WriteConsole( hStdOut, ach2, strlen(ach2), &cb, NULL); } OutputDebugString(ach2); } _except( EXCEPTION_EXECUTE_HANDLER) { // return failure cch = 0; } SetLastError(dwErr); return cch; } #else #ifdef __cplusplus extern "C" { #endif BOOL WINAPI DbgInitOSS( OssGlobal *pog); int WINAPIV DbgPrintf(DWORD dwSubSystemId, LPCSTR lpFmt, ...); #ifdef __cplusplus } // balance of extern "C" #endif //+------------------------------------------------------------------------- // // Function: DbgInitOSS // // Synopsis: Do OSS init for debug. Do nothing in retail builds // // Returns: TRUE // // Note: Always FRONT_ALIGN encoding // //-------------------------------------------------------------------------- BOOL WINAPI DbgInitOSS( OssGlobal *pog) { return(TRUE); } //+------------------------------------------------------------------------- // // Function: DbgPrintf // // Synopsis: outputs debug info to stdout and debugger // Nothing in retail builds // // Returns: number of chars output // //-------------------------------------------------------------------------- int WINAPIV DbgPrintf(DWORD dwSubSystemId, LPCSTR lpFmt, ...) { return(0); } #endif // DBG