Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

542 lines
9.3 KiB

/*++
Copyright (c) 1994-1999 Microsoft Corporation
Module Name :
debugafx.cpp
Abstract:
Debugging routines using AFX/MFC extensions
Author:
Ronald Meijer (ronaldm)
Project:
Internet Services Manager
Revision History:
--*/
//
// Include Files
//
#include "stdafx.h"
#include "common.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
#if defined(_DEBUG) || DBG
int
IISUIFireAssert(
const char * filename,
const char * timestamp,
int linenum,
const char * expr
)
{
char sz[4096];
char * pch = sz;
pch += wsprintfA(pch,
"-------------------------------------------------------------------------------\n"
"ASSERT FAILURE!\n"
"-------------------------------------------------------------------------------\n"
"File:\t\t%s\n"
"Line:\t\t%u\n"
"Time Stamp:\t%s\n"
"-------------------------------------------------------------------------------\n",
filename, linenum, timestamp
);
if (expr)
{
wsprintfA(pch, "Expression:\t%s\n"
"-------------------------------------------------------------------------------\n",
expr
);
}
TRACEEOL(sz);
int nReturn = MessageBoxA(
NULL,
sz,
"ASSERT FAILURE!",
MB_ABORTRETRYIGNORE | MB_DEFBUTTON1 | MB_ICONHAND
);
if (nReturn == IDABORT)
{
exit(-1);
}
//
// Return 1 to break, 0 to ignore
//
return (nReturn == IDRETRY);
}
#endif // _DEBUG || DBG
#if defined(_DEBUG) || DBG
#ifndef _DEBUG
//
// SDK build links with retail MFC. Swiped code from MFC sources. Some
// modifications.
//
COMDLL CDumpContext afxDump;
COMDLL BOOL afxTraceEnabled = TRUE;
void
CDumpContext::OutputString(LPCTSTR lpsz)
{
if (m_pFile == NULL)
{
OutputDebugString(lpsz);
return;
}
m_pFile->Write(lpsz, lstrlen(lpsz)*sizeof(TCHAR));
}
CDumpContext::CDumpContext(CFile * pFile)
{
if (pFile)
{
ASSERT_PTR(pFile);
}
m_pFile = pFile;
m_nDepth = 0;
}
void
CDumpContext::Flush()
{
if (m_pFile)
{
m_pFile->Flush();
}
}
CDumpContext& CDumpContext::operator<<(LPCTSTR lpsz)
{
if (lpsz == NULL)
{
OutputString(_T("(NULL)"));
return *this;
}
if (m_pFile == NULL)
{
TCHAR szBuffer[512];
LPTSTR lpBuf = szBuffer;
while (*lpsz != '\0')
{
if (lpBuf > szBuffer + ARRAY_SIZE(szBuffer) - 3)
{
*lpBuf = '\0';
OutputString(szBuffer);
lpBuf = szBuffer;
}
if (*lpsz == '\n')
{
*lpBuf++ = '\r';
}
*lpBuf++ = *lpsz++;
}
*lpBuf = '\0';
OutputString(szBuffer);
return *this;
}
m_pFile->Write(lpsz, lstrlen(lpsz) * sizeof(TCHAR));
return *this;
}
CDumpContext& CDumpContext::operator<<(BYTE by)
{
TCHAR szBuffer[32];
wsprintf(szBuffer, _T("%d"), (int)by);
OutputString(szBuffer);
return *this;
}
CDumpContext& CDumpContext::operator<<(WORD w)
{
TCHAR szBuffer[32];
wsprintf(szBuffer, _T("%u"), (UINT) w);
OutputString(szBuffer);
return *this;
}
CDumpContext& CDumpContext::operator<<(UINT u)
{
TCHAR szBuffer[32];
wsprintf(szBuffer, _T("0x%X"), u);
OutputString(szBuffer);
return *this;
}
CDumpContext& CDumpContext::operator<<(LONG l)
{
TCHAR szBuffer[32];
wsprintf(szBuffer, _T("%ld"), l);
OutputString(szBuffer);
return *this;
}
CDumpContext& CDumpContext::operator<<(DWORD dw)
{
TCHAR szBuffer[32];
wsprintf(szBuffer, _T("%lu"), dw);
OutputString(szBuffer);
return *this;
}
CDumpContext& CDumpContext::operator<<(int n)
{
TCHAR szBuffer[32];
wsprintf(szBuffer, _T("%d"), n);
OutputString(szBuffer);
return *this;
}
CDumpContext& CDumpContext::operator<<(const CObject * pOb)
{
if (pOb == NULL)
{
*this << _T("NULL");
}
else
{
pOb->Dump(*this);
}
return *this;
}
CDumpContext& CDumpContext::operator<<(const CObject & ob)
{
return *this << &ob;
}
CDumpContext& CDumpContext::operator<<(const void * lp)
{
TCHAR szBuffer[32];
wsprintf(szBuffer, _T("$%p"), lp);
OutputString(szBuffer);
return *this;
}
void
CDumpContext::HexDump(
LPCTSTR lpszLine,
BYTE * pby,
int nBytes,
int nWidth
)
{
ASSERT(nBytes > 0);
ASSERT(nWidth > 0);
ASSERT(AfxIsValidString(lpszLine));
ASSERT(AfxIsValidAddress(pby, nBytes, FALSE));
int nRow = 0;
TCHAR szBuffer[32];
while (nBytes--)
{
if (nRow == 0)
{
wsprintf(szBuffer, lpszLine, pby);
*this << szBuffer;
}
wsprintf(szBuffer, _T(" %02X"), *pby++);
*this << szBuffer;
if (++nRow >= nWidth)
{
*this << _T("\n");
nRow = 0;
}
}
if (nRow != 0)
{
*this << _T("\n");
}
}
/////////////////////////////////////////////////////////////////////////////
#ifdef _UNICODE
CDumpContext & CDumpContext::operator<<(LPCSTR lpsz)
{
if (lpsz == NULL)
{
OutputString(L"(NULL)");
return *this;
}
TCHAR szBuffer[512];
_mbstowcsz(szBuffer, lpsz, ARRAY_SIZE(szBuffer));
return *this << szBuffer;
}
#else //_UNICODE
CDumpContext& CDumpContext::operator<<(LPCWSTR lpsz)
{
if (lpsz == NULL)
{
OutputString("(NULL)");
return *this;
}
char szBuffer[512];
_wcstombsz(szBuffer, lpsz, ARRAY_SIZE(szBuffer));
return *this << szBuffer;
}
#endif //!_UNICODE
//
// End of block of code copied from MFC
//
#endif // _DEBUG
LPCSTR
DbgFmtPgm(
IN LPCSTR szFn,
IN int line
)
/*++
Routine Description:
Format debugging string containing file name and line number. Remove
the path portion of the file name if present.
Arguments:
LPCSTR szFn : File name (ANSI)
int line : Line number
Return Value:
Pointer to the internal buffer
--*/
{
LPCSTR pszTail = szFn + lstrlenA(szFn);
static CHAR szBuff[MAX_PATH + 1];
for ( /**/; pszTail > szFn; --pszTail)
{
if (*pszTail == '\\' || *pszTail == ':')
{
++pszTail;
break;
}
}
wsprintfA(szBuff, "[%s:%d] ", pszTail, line);
return szBuff;
}
CDumpContext &
operator <<(
IN OUT CDumpContext & out,
IN ENUM_DEBUG_AFX edAfx
)
/*++
Routine Description:
Output debugging control character to the debug context
Arguments:
CDumpContext & out : Output debugging context
edAfx : Control character
Return Value:
Output debugging context reference
--*/
{
static CHAR * szEol = "\r\n";
switch (edAfx)
{
case EDBUG_AFX_EOL:
out << szEol;
break;
default:
break;
}
return out;
}
#ifndef UNICODE
CDumpContext &
operator <<(
IN OUT CDumpContext & out,
IN LPCWSTR pwchStr
)
/*++
Routine Description:
Insert a wide-character string into the output stream. For non-UNICODE only,
as this functions would be handled by the generic 'T' function otherwise.
Arguments:
CDumpContext & out : Output debugging context
pwchStr : Wide character string
Return Value:
Output debugging context reference
--*/
{
size_t cwch ;
if (pwchStr == NULL)
{
out << "<null>";
}
else if ((cwch = ::wcslen(pwchStr )) > 0)
{
CHAR * pszTemp = (LPSTR)AllocMem(cwch + 2);
if (pszTemp != NULL)
{
for (int i = 0; pwchStr[i]; ++i)
{
pszTemp[i] = (CHAR)pwchStr[i];
}
pszTemp[i] = 0;
out << pszTemp;
FreeMem(pszTemp);
}
else
{
out << "<memerr>";
}
}
else
{
out << "\"\"";
}
return out;
}
#endif // UNICODE
CDumpContext &
operator <<(
IN CDumpContext & out,
IN const GUID & guid
)
/*++
Routine Description:
Dump a GUID to the debugger
Arguments:
CDumpContext & out : Output debugging context
GUID & guid : GUID
Return Value:
Output debugging context reference
--*/
{
out << "{ "
<< guid.Data1
<< ","
<< guid.Data2
<< ","
<< guid.Data3
<< ","
<< guid.Data4
<< "}";
return out;
}
#endif // _DEBUG