EDKDEBUG.C

// --edkdebug.c----------------------------------------------------------------- 
//
// Functions to log debugging information in DEBUG builds.
//
// Copyright (C) Microsoft Corp. 1986-1996. All Rights Reserved.
// -----------------------------------------------------------------------------

#define _PRIVATE_EDKDEBUG_H
#define _PRIVATE_MEMORY_H
#include "edk.h"

#define REPORT_ERROR(x) \
_WriteDebugString("error: %s, %lu, %s\n", __FILE__,__LINE__,(x))

static LPSTR szNullA = "";

//$--GetComponentFileName-------------------------------------------------------
// Return a text representation of a component file name.
// -----------------------------------------------------------------------------
static LPSTR GetComponentFileName( // RETURNS: component file name
IN LPSTR lpszFile) // pointer to file name
{
LPSTR pszT = NULL;
LPSTR psz = NULL;

if(IsBadStringPtrA(lpszFile, INFINITE))
{
return(szNullA);
}

psz = lpszFile;

pszT = lpszFile + lstrlen(lpszFile);

while(pszT >= lpszFile)
{
if(*pszT == '\\')
{
psz = pszT;
}
else if((*pszT == ':'))
{
psz = pszT;
break;
}

pszT--;
}

if((*psz == '\\') || (*psz == ':'))
{
psz++;
}

return(psz);
}

//$--BoolName-------------------------------------------------------------------
// Return a text representation of a boolean value.
// -----------------------------------------------------------------------------
static LPSTR BoolName( // RETURNS: textized boolean value
IN BOOL fStatus) // boolean value
{
switch(fStatus)
{
case TRUE:
return("TRUE");
case FALSE:
return("FALSE");
default:
return("UNKNOWN");
}
}

//$--DebugLevelName-------------------------------------------------------------
// Return a text representation of a debug level.
// -----------------------------------------------------------------------------
static LPSTR DebugLevelName( // RETURNS: textized debug level
IN DEBUGLEVEL eLevel) // debug level
{
switch(eLevel)
{
case D_PUBLIC:
return("D_PUBLIC");
case D_PRIVATE:
return("D_PRIVATE");
case D_ERROR:
return("D_ERROR");
case D_WARNING:
return("D_WARNING");
case D_STATUS:
return("D_STATUS");
case D_ACTION:
return("D_ACTION");
case D_OTHER:
return("D_OTHER");
default:
return("UNKNOWN");
}
}

//$--_ShowAssert----------------------------------------------------------------
// Prompts user for what action to take on an assertion failure.
// -----------------------------------------------------------------------------
static void _ShowAssert( // RETURNS: nothing
IN LPSTR lpszFile, // source file name
IN ULONG ulLine) // source line number
{
int n = 0;
char lpsz[BUFSIZ+1] = {0};

LPSTR lpszPrompt
= "%s - line %lu\n"
"\n"
"Click on ABORT to exit the application.\n"
"Click on RETRY to debug the application.\n"
"Click on IGNORE to continue.";

__try
{
n = _snprintf(
lpsz,
BUFSIZ,
lpszPrompt,
GetComponentFileName(lpszFile),
ulLine);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
REPORT_ERROR(_exception_code());
n = -1;
}

if(n < 0)
{
goto cleanup;
}

n = MessageBox(NULL,
lpsz,
"Assertion Failure",
MB_ABORTRETRYIGNORE | MB_ICONSTOP | MB_TASKMODAL);

switch(n)
{
case IDABORT:
// User chose to terminate program
ExitProcess(0);
break;
case IDRETRY:
// User chose to trap into the debugger
DebugBreak();
break;
case IDIGNORE:
// User chose to continue execution
break;
default:
break;
}

cleanup:

return;
}

//$--_Assert--------------------------------------------------------------------
//
// Write to the debug log file and/or evaluate assertion.
//
// -----------------------------------------------------------------------------
void _Assert( // RETURNS: nothing
IN LPSTR lpszTag, // tag name
IN LPSTR lpszFile, // source file name
IN ULONG ulLine, // source line number
IN DEBUGLEVEL Level, // assertion level
IN BOOL fValue, // assertion value
IN LPSTR lpszFormat, // format string
...) // arguments
{
char lpsz[BUFSIZ+1] = {0};
va_list va_alist = {0};
SYSTEMTIME st = {0};
FILETIME ft = {0};
BOOL fRet = FALSE;

_InitDebugFile();

if(_StatusDebugLevel(Level) == FALSE)
{
goto cleanup;
}

if((lpszTag == NULL) || IsBadStringPtrA(lpszTag, INFINITE))
{
REPORT_ERROR(ERROR_INVALID_PARAMETER);
goto cleanup;
}

if((lpszFile == NULL) || IsBadStringPtrA(lpszFile, INFINITE))
{
REPORT_ERROR(ERROR_INVALID_PARAMETER);
goto cleanup;
}

if((lpszFormat == NULL) || IsBadStringPtrA(lpszFormat, INFINITE))
{
REPORT_ERROR(ERROR_INVALID_PARAMETER);
goto cleanup;
}

_LockDebugFile();

if(((Level != D_ERROR) && (Level != D_WARNING)) ||
(((Level == D_ERROR) || (Level == D_WARNING)) && (fValue == FALSE)))
{
__try
{
GetSystemTime(&st);

fRet = SystemTimeToFileTime(&st, &ft);

if(fRet != TRUE)
{
ft.dwLowDateTime = 0;
ft.dwHighDateTime = 0;
}

_WriteDebugFile(
"%08lX%08lX %s - process %lu, thread %lu, level %s, file %s, line %lu: ",
ft.dwHighDateTime,
ft.dwLowDateTime,
lpszTag,
GetCurrentProcessId(),
GetCurrentThreadId(),
DebugLevelName(Level),
lpszFile,
ulLine);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
REPORT_ERROR(_exception_code());
}

__try
{
va_start( va_alist, lpszFormat );

_vsnprintf( lpsz, BUFSIZ, lpszFormat, va_alist );

va_end( va_alist );

_WriteDebugFile("%s", lpsz);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
REPORT_ERROR(_exception_code());
}
}

_UnlockDebugFile();

cleanup:

if(_StatusShowAssert() && (fValue == FALSE) && (Level == D_ERROR))
{
_ShowAssert(lpszFile, ulLine);
}

return;
}