515 lines
11 KiB
C++
515 lines
11 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// 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 <windows.h>
|
|
#include <asn1code.h>
|
|
|
|
#if DBG
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <memory.h>
|
|
#include <string.h>
|
|
#include <process.h>
|
|
#include <time.h>
|
|
#include <crtdbg.h>
|
|
|
|
#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
|