455 lines
8.3 KiB
C++
455 lines
8.3 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1999
|
|
//
|
|
// File: debug.cpp
|
|
//
|
|
// Contents: Debug sub system APIs implementation
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include <pch.cpp>
|
|
|
|
#pragma hdrstop
|
|
|
|
#define DBG_CERTSRV_DEBUG_PRINT
|
|
|
|
#ifdef DBG_CERTSRV_DEBUG_PRINT
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
|
FILE *g_pfLog;
|
|
DWORD g_dwPrintMask = ~(DBG_SS_INFO | DBG_SS_MODLOAD | DBG_SS_NOQUIET);
|
|
CRITICAL_SECTION g_DBGCriticalSection;
|
|
BOOL g_fDBGCSInit = FALSE;
|
|
|
|
FNLOGSTRING *s_pfnLogString = NULL;
|
|
|
|
|
|
const char *
|
|
DbgGetSSString(
|
|
IN DWORD dwSubSystemId)
|
|
{
|
|
char const *psz = NULL;
|
|
|
|
if (MAXDWORD != dwSubSystemId)
|
|
{
|
|
switch (dwSubSystemId & ~DBG_SS_INFO)
|
|
{
|
|
case DBG_SS_ERROR: psz = "CertError"; break;
|
|
case DBG_SS_ASSERT: psz = "CertAssert"; break;
|
|
case DBG_SS_CERTHIER: psz = "CertHier"; break;
|
|
case DBG_SS_CERTREQ: psz = "CertReq"; break;
|
|
case DBG_SS_CERTUTIL: psz = "CertUtil"; break;
|
|
case DBG_SS_CERTSRV: psz = "CertSrv"; break;
|
|
case DBG_SS_CERTADM: psz = "CertAdm"; break;
|
|
case DBG_SS_CERTCLI: psz = "CertCli"; break;
|
|
case DBG_SS_CERTDB: psz = "CertDB"; break;
|
|
case DBG_SS_CERTENC: psz = "CertEnc"; break;
|
|
case DBG_SS_CERTEXIT: psz = "CertExit"; break;
|
|
case DBG_SS_CERTIF: psz = "CertIF"; break;
|
|
case DBG_SS_CERTMMC: psz = "CertMMC"; break;
|
|
case DBG_SS_CERTOCM: psz = "CertOCM"; break;
|
|
case DBG_SS_CERTPOL: psz = "CertPol"; break;
|
|
case DBG_SS_CERTVIEW: psz = "CertView"; break;
|
|
case DBG_SS_CERTBCLI: psz = "CertBCli"; break;
|
|
case DBG_SS_CERTJET: psz = "CertJet"; break;
|
|
case DBG_SS_CERTLIBXE: psz = "CertLibXE"; break;
|
|
case DBG_SS_CERTLIB: psz = "CertLib"; break;
|
|
case DBG_SS_AUDIT: psz = "CertAudit"; break;
|
|
default: psz = "Cert"; break;
|
|
}
|
|
}
|
|
return(psz);
|
|
}
|
|
|
|
|
|
DWORD
|
|
myatolx(
|
|
char const *psz)
|
|
{
|
|
DWORD dw = 0;
|
|
|
|
while (isxdigit(*psz))
|
|
{
|
|
char ch = *psz++;
|
|
|
|
if (isdigit(ch))
|
|
{
|
|
ch -= '0';
|
|
}
|
|
else if (isupper(ch))
|
|
{
|
|
ch += 10 - 'A';
|
|
}
|
|
else
|
|
{
|
|
ch += 10 - 'a';
|
|
}
|
|
dw = (dw << 4) | ch;
|
|
}
|
|
return(dw);
|
|
}
|
|
|
|
|
|
VOID
|
|
DbgLogDateTime(
|
|
IN CHAR const *pszPrefix)
|
|
{
|
|
if (NULL != g_pfLog)
|
|
{
|
|
WCHAR *pwszDate;
|
|
FILETIME ft;
|
|
SYSTEMTIME st;
|
|
|
|
fprintf(g_pfLog, "%hs: ", pszPrefix);
|
|
GetSystemTime(&st);
|
|
if (SystemTimeToFileTime(&st, &ft))
|
|
{
|
|
if (S_OK == myGMTFileTimeToWszLocalTime(&ft, TRUE, &pwszDate))
|
|
{
|
|
fprintf(g_pfLog, "%ws", pwszDate);
|
|
LocalFree(pwszDate);
|
|
}
|
|
}
|
|
fprintf(g_pfLog, "\n");
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
DbgCloseLogFile()
|
|
{
|
|
if(g_fDBGCSInit)
|
|
{
|
|
EnterCriticalSection(&g_DBGCriticalSection);
|
|
if (NULL != g_pfLog)
|
|
{
|
|
DbgLogDateTime("Closed Log");
|
|
fclose(g_pfLog);
|
|
g_pfLog = NULL;
|
|
}
|
|
LeaveCriticalSection(&g_DBGCriticalSection);
|
|
}
|
|
}
|
|
|
|
|
|
char const szHeader[] = "\n========================================================================\n";
|
|
|
|
VOID
|
|
DbgOpenLogFile(
|
|
OPTIONAL IN CHAR const *pszFile)
|
|
{
|
|
if (NULL != pszFile)
|
|
{
|
|
BOOL fAppend = FALSE;
|
|
UINT cch;
|
|
char aszLogFile[MAX_PATH];
|
|
|
|
if ('+' == *pszFile)
|
|
{
|
|
pszFile++;
|
|
fAppend = TRUE;
|
|
}
|
|
if (NULL == strchr(pszFile, '\\'))
|
|
{
|
|
cch = GetWindowsDirectoryA(aszLogFile, ARRAYSIZE(aszLogFile));
|
|
if (0 != cch)
|
|
{
|
|
if (L'\\' != aszLogFile[cch - 1])
|
|
{
|
|
strcat(aszLogFile, "\\");
|
|
}
|
|
strcat(aszLogFile, pszFile);
|
|
pszFile = aszLogFile;
|
|
}
|
|
}
|
|
|
|
DbgCloseLogFile();
|
|
|
|
if (g_fDBGCSInit)
|
|
{
|
|
EnterCriticalSection(&g_DBGCriticalSection);
|
|
while (TRUE)
|
|
{
|
|
g_pfLog = fopen(pszFile, fAppend? "at" : "wt");
|
|
if (NULL == g_pfLog)
|
|
{
|
|
_PrintError(E_FAIL, "fopen(Log)");
|
|
}
|
|
else
|
|
{
|
|
if (fAppend)
|
|
{
|
|
DWORD cbLogMax = 0;
|
|
char const *pszEnvVar;
|
|
|
|
pszEnvVar = getenv(szCERTSRV_LOGMAX);
|
|
if (NULL != pszEnvVar)
|
|
{
|
|
cbLogMax = myatolx(pszEnvVar);
|
|
}
|
|
if (CBLOGMAXAPPEND > cbLogMax)
|
|
{
|
|
cbLogMax = CBLOGMAXAPPEND;
|
|
}
|
|
if (0 == fseek(g_pfLog, 0L, SEEK_END) &&
|
|
MAXDWORD != cbLogMax)
|
|
{
|
|
LONG lcbLog = ftell(g_pfLog);
|
|
|
|
if (0 > lcbLog || cbLogMax < (DWORD) lcbLog)
|
|
{
|
|
fclose(g_pfLog);
|
|
g_pfLog = NULL;
|
|
fAppend = FALSE;
|
|
continue;
|
|
}
|
|
}
|
|
fprintf(g_pfLog, szHeader);
|
|
}
|
|
DbgLogDateTime("Opened Log");
|
|
}
|
|
break;
|
|
}
|
|
LeaveCriticalSection(&g_DBGCriticalSection);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
DbgInit(
|
|
IN BOOL fOpenDefaultLog)
|
|
{
|
|
static BOOL s_fFirst = TRUE;
|
|
|
|
if (s_fFirst)
|
|
{
|
|
char const *pszEnvVar;
|
|
|
|
__try
|
|
{
|
|
InitializeCriticalSection(&g_DBGCriticalSection);
|
|
g_fDBGCSInit = TRUE;
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
return;
|
|
}
|
|
s_fFirst = FALSE;
|
|
|
|
pszEnvVar = getenv(szCERTSRV_DEBUG);
|
|
if (NULL != pszEnvVar)
|
|
{
|
|
g_dwPrintMask = myatolx(pszEnvVar);
|
|
}
|
|
else
|
|
{
|
|
HRESULT hr;
|
|
DWORD PrintMask;
|
|
|
|
hr = myGetCertRegDWValue(
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
wszREGCERTSRVDEBUG,
|
|
&PrintMask);
|
|
if (S_OK == hr)
|
|
{
|
|
g_dwPrintMask = PrintMask;
|
|
}
|
|
}
|
|
|
|
if (fOpenDefaultLog && NULL == g_pfLog)
|
|
{
|
|
pszEnvVar = getenv(szCERTSRV_LOGFILE);
|
|
DbgOpenLogFile(pszEnvVar);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
BOOL
|
|
DbgIsSSActive(
|
|
IN DWORD dwSSIn)
|
|
{
|
|
DbgInit(TRUE);
|
|
if (MAXDWORD == dwSSIn)
|
|
{
|
|
return(TRUE);
|
|
}
|
|
if ((DBG_SS_INFO & dwSSIn) && 0 == (DBG_SS_INFO & g_dwPrintMask))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
return(0 != (~DBG_SS_INFO & g_dwPrintMask & dwSSIn));
|
|
}
|
|
|
|
|
|
VOID
|
|
DbgLogStringInit(
|
|
IN FNLOGSTRING *pfnLogString)
|
|
{
|
|
if (NULL == s_pfnLogString)
|
|
{
|
|
s_pfnLogString = pfnLogString;
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
DbgPrintfInit(
|
|
OPTIONAL IN CHAR const *pszFile)
|
|
{
|
|
DbgInit(NULL == pszFile);
|
|
DbgOpenLogFile(pszFile);
|
|
}
|
|
|
|
|
|
VOID
|
|
fputsStripCR(
|
|
IN BOOL fUnicode,
|
|
IN char const *psz,
|
|
IN FILE *pf)
|
|
{
|
|
while ('\0' != *psz)
|
|
{
|
|
DWORD i;
|
|
|
|
i = strcspn(psz, "\r");
|
|
if (0 != i)
|
|
{
|
|
if (fUnicode)
|
|
{
|
|
if (IOBUNALIGNED(pf))
|
|
{
|
|
fflush(pf); // fails when running as a service
|
|
}
|
|
if (IOBUNALIGNED(pf))
|
|
{
|
|
fprintf(pf, " ");
|
|
fflush(pf);
|
|
}
|
|
fwprintf(pf, L"%.*hs", i, psz);
|
|
}
|
|
else
|
|
{
|
|
fprintf(pf, "%.*hs", i, psz);
|
|
}
|
|
psz += i;
|
|
}
|
|
if ('\r' == *psz)
|
|
{
|
|
psz++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: DbgPrintf
|
|
//
|
|
// Synopsis: outputs debug info to stdout and debugger
|
|
//
|
|
// Returns: number of chars output
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
int WINAPIV
|
|
DbgPrintf(
|
|
IN DWORD dwSubSystemId,
|
|
IN LPCSTR lpFmt,
|
|
...)
|
|
{
|
|
va_list arglist;
|
|
CHAR ach1[4096];
|
|
CHAR ach2[4096 + 56];
|
|
char *pch = NULL;
|
|
char const *pszPrefix;
|
|
int cch = 0;
|
|
HANDLE hStdOut;
|
|
DWORD cb;
|
|
DWORD dwErr;
|
|
BOOL fCritSecEntered = FALSE;
|
|
|
|
dwErr = GetLastError();
|
|
|
|
if (DbgIsSSActive(dwSubSystemId))
|
|
{
|
|
_try
|
|
{
|
|
va_start(arglist, lpFmt);
|
|
|
|
cch = _vsnprintf(ach1, sizeof(ach1), lpFmt, arglist);
|
|
|
|
va_end(arglist);
|
|
|
|
if (0 > cch)
|
|
{
|
|
pch = &ach1[sizeof(ach1) - 5];
|
|
strcpy(pch, "...\n");
|
|
}
|
|
pch = ach1;
|
|
|
|
pszPrefix = DbgGetSSString(dwSubSystemId);
|
|
if (NULL != pszPrefix)
|
|
{
|
|
cch = _snprintf(
|
|
ach2,
|
|
sizeof(ach2),
|
|
"%hs: %hs",
|
|
DbgGetSSString(dwSubSystemId),
|
|
ach1);
|
|
if (0 > cch)
|
|
{
|
|
pch = &ach2[sizeof(ach2) - 5];
|
|
strcpy(pch, "...\n");
|
|
}
|
|
pch = ach2;
|
|
}
|
|
|
|
EnterCriticalSection(&g_DBGCriticalSection);
|
|
fCritSecEntered = TRUE;
|
|
if (!IsDebuggerPresent())
|
|
{
|
|
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
if (hStdOut != INVALID_HANDLE_VALUE)
|
|
{
|
|
// WriteConsoleA drops the output on the floor when stdout
|
|
// is redirected to a file.
|
|
// WriteConsoleA(hStdOut, pch, strlen(pch), &cb, NULL);
|
|
|
|
fputsStripCR(TRUE, pch, stdout);
|
|
fflush(stdout);
|
|
}
|
|
}
|
|
if (NULL != g_pfLog)
|
|
{
|
|
fputsStripCR(FALSE, pch, g_pfLog);
|
|
fflush(g_pfLog);
|
|
}
|
|
OutputDebugStringA(pch);
|
|
}
|
|
_except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
// return failure
|
|
cch = 0;
|
|
}
|
|
}
|
|
if (fCritSecEntered)
|
|
{
|
|
LeaveCriticalSection(&g_DBGCriticalSection);
|
|
}
|
|
if (NULL != pch && NULL != s_pfnLogString)
|
|
{
|
|
(*s_pfnLogString)(pch);
|
|
}
|
|
SetLastError(dwErr);
|
|
return(cch);
|
|
}
|
|
#endif // DBG_CERTSRV_DEBUG_PRINT
|