windows-nt/Source/XPSP1/NT/ds/security/cryptoapi/common/debug/debug.cpp
2020-09-26 16:20:57 +08:00

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