/*********************************************************************** SRVDBG.CPP Server Debug Support Copyright (C) 1995 Microsoft Corporation All rights reserved. Created on: 05/25/95 ************************************************************************/ //#include "stdafx.h" #include "pch.h" static HANDLE g_hEventLog = NULL; BOOL g_fWantInt3 = TRUE; char g_szDbgModPath[MAX_PATH] = ""; /*********************************************************************** FUNCTION: SRVDBG_Init Initialize Server Debugging Support If NULL is passed for the path, this routine will attempt to determine the path through GetModuleFileName, which may not be accurate for DLLs, depending on the calling context of the call to this routine (won't work for DLLs unless called from ProcessAttach notification). Created on: 05/26/95 ************************************************************************/ BOOL SRVDBG_Init(LPSTR lpszSource, LPSTR lpszPath, BOOL fWantInt3) { g_fWantInt3 = fWantInt3; if ( !lpszSource ) return (FALSE); if (!lpszPath) GetModuleFileName(NULL, g_szDbgModPath, sizeof(g_szDbgModPath)); else lstrcpy(g_szDbgModPath, lpszPath); Assert(!g_hEventLog); g_hEventLog = RegisterEventSource(NULL, lpszSource ); return (g_hEventLog != NULL); } /*********************************************************************** FUNCTION: SRVDBG_Terminate Terminate Server Debugging Support Created on: 05/26/95 ************************************************************************/ BOOL SRVDBG_Terminate( void ) { if ( !g_hEventLog ) return ( FALSE ); BOOL fDeregisterEventSource = DeregisterEventSource( g_hEventLog ); Assert(fDeregisterEventSource); g_hEventLog = NULL; return fDeregisterEventSource; } /*********************************************************************** FUNCTION: SRVDBG_ClearLog Clear debug event log. SRVDBG_Init must be called first. Created on: 05/26/95 ************************************************************************/ BOOL SRVDBG_ClearLog( void ) { if ( !g_hEventLog ) return ( FALSE ); return ( ClearEventLog( g_hEventLog, NULL ) ); } /*********************************************************************** FUNCTION: SRVDBG_Error Definition: Log error event SRVDBG_Init must be called first. Created on: 12/09/97 Comment: This was a macro before. ************************************************************************/ void SRVDBG_Error( LPCSTR lpsz ) { SRVDBG_ReportEvent( SRVDBG_ERROR_TYPE, SRVDBG_ERROR, lpsz, NULL, NULL ); } /*********************************************************************** FUNCTION: SRVDBG_Error2 Definition: Log error event SRVDBG_Init must be called first. Created on: 12/09/97 Comment: This was a macro before. ************************************************************************/ void SRVDBG_Error2( LPCSTR lpsz, LPCSTR lpsz2) { SRVDBG_ReportEvent( SRVDBG_ERROR_TYPE, SRVDBG_ERROR, lpsz, lpsz2, NULL ); } /*********************************************************************** FUNCTION: SRVDBG_Error3 Definition: Log error event SRVDBG_Init must be called first. Created on: 12/09/97 Comment: This was a macro before. ************************************************************************/ void SRVDBG_Error3( LPCSTR lpsz, LPCSTR lpsz2, LPCSTR lpsz3) { SRVDBG_ReportEvent( SRVDBG_ERROR_TYPE, SRVDBG_ERROR, lpsz, lpsz2, lpsz3 ); } /*********************************************************************** FUNCTION: SRVDBG_Info Definition: Log error event SRVDBG_Init must be called first. Created on: 12/09/97 Comment: This was a macro before. ************************************************************************/ void SRVDBG_Info( LPCSTR lpsz ) { SRVDBG_ReportEvent( SRVDBG_INFO_TYPE, SRVDBG_INFO, lpsz, NULL, NULL ); } /*********************************************************************** FUNCTION: SRVDBG_Info2 Definition: Log error event SRVDBG_Init must be called first. Created on: 12/09/97 Comment: This was a macro before. ************************************************************************/ void SRVDBG_Info2( LPCSTR lpsz, LPCSTR lpsz2 ) { SRVDBG_ReportEvent( SRVDBG_INFO_TYPE, SRVDBG_INFO, lpsz, lpsz2, NULL ); } /*********************************************************************** FUNCTION: SRVDBG_Info3 Definition: Log error event SRVDBG_Init must be called first. Created on: 12/09/97 Comment: This was a macro before. ************************************************************************/ void SRVDBG_Info3( LPCSTR lpsz, LPCSTR lpsz2, LPCSTR lpsz3 ) { SRVDBG_ReportEvent( SRVDBG_INFO_TYPE, SRVDBG_INFO, lpsz, lpsz2, lpsz3 ); } /*********************************************************************** FUNCTION: SRVDBG_Warning Definition: Log error event SRVDBG_Init must be called first. Created on: 12/09/97 Comment: This was a macro before. ************************************************************************/ void SRVDBG_Warning( LPCSTR lpsz ) { SRVDBG_ReportEvent( SRVDBG_WARNING_TYPE, SRVDBG_WARNING, lpsz, NULL, NULL ); } /*********************************************************************** FUNCTION: SRVDBG_Warning2 Definition: Log error event SRVDBG_Init must be called first. Created on: 12/09/97 Comment: This was a macro before. ************************************************************************/ void SRVDBG_Warning2( LPCSTR lpsz, LPCSTR lpsz2 ) { SRVDBG_ReportEvent( SRVDBG_WARNING_TYPE, SRVDBG_WARNING, lpsz, lpsz2, NULL ); } /*********************************************************************** FUNCTION: SRVDBG_Warning3 Definition: Log error event SRVDBG_Init must be called first. Created on: 12/09/97 Comment: This was a macro before. ************************************************************************/ void SRVDBG_Warning3( LPCSTR lpsz, LPCSTR lpsz2, LPCSTR lpsz3 ) { SRVDBG_ReportEvent( SRVDBG_WARNING_TYPE, SRVDBG_WARNING, lpsz, lpsz2, lpsz3 ); } void SRVDBG_ErrorEvt( DWORD IDEvent, LPCSTR lpsz ) { SRVDBG_ReportEvent( SRVDBG_ERROR_TYPE, IDEvent, lpsz, NULL, NULL ); } void SRVDBG_WarningEvt( DWORD IDEvent, LPCSTR lpsz ) { SRVDBG_ReportEvent( SRVDBG_WARNING_TYPE, IDEvent, lpsz, NULL, NULL ); } void SRVDBG_InfoEvt( DWORD IDEvent, LPCSTR lpsz ) { SRVDBG_ReportEvent( SRVDBG_INFO_TYPE, IDEvent, lpsz, NULL, NULL ); } void SRVDBG_Assert( LPCSTR lpsz ) { SRVDBG_ErrorEvt( SRVDBG_ASSERT, lpsz ); } /*********************************************************************** FUNCTION: SBRDBG_ReportEvent Report error, warning, or information. SRVDBG_Init must be called first. History Created on: 05/26/95 06/05/96 cmason Added special support for getting Assert's logged into the QScript Thread Local Storage trave buffer so that on Aborts and Exceptions, the Assert will show up in the dump of the trace buffer. ************************************************************************/ BOOL SRVDBG_ReportEvent( WORD fwEventType, DWORD IDEvent, LPCSTR lpsz, LPCSTR lpsz2, LPCSTR lpsz3) { LPCSTR plpszT[5]; WORD cStrings; BOOL fSuccess; cStrings = 5; plpszT[0] = g_szDbgModPath; plpszT[1] = ""; // was product id plpszT[2] = lpsz ? lpsz : ""; plpszT[3] = lpsz2 ? lpsz2 : ""; plpszT[4] = lpsz3 ? lpsz3 : ""; // go ahead and send the event to anyone watching debug output for (int i=0; i= ptb->cchBuf) { // Copy *last* cchBuf chars memcpy(ptb->rgch, lpBuffer + (cbOut - ptb->cchBuf), ptb->cchBuf); ptb->ichStart = 0; ptb->ichEnd = ptb->cchBuf-1; } else { // Is output larger than remaining contig space? if (cbOut > ptb->cchBuf - ptb->ichEnd) { memcpy(&(ptb->rgch[ptb->ichEnd]), lpBuffer, ptb->cchBuf - ptb->ichEnd); memcpy(ptb->rgch, lpBuffer+(ptb->cchBuf-ptb->ichEnd), cbOut-(ptb->cchBuf-ptb->ichEnd)); ptb->ichStart = cbOut-(ptb->cchBuf-ptb->ichEnd); ptb->ichEnd = ptb->ichStart-1; } else { memcpy(&ptb->rgch[ptb->ichEnd], lpBuffer, cbOut); if (ptb->ichStart > ptb->ichEnd) { ptb->ichEnd += cbOut-1; ptb->ichStart = ptb->ichEnd+1; } else ptb->ichEnd += cbOut-1; } } } } #ifndef FDbgFalse /*!-------------------------------------------------------------------------- FDbgFalse Returns false, but insures that debug code page is in memory. Also makes a handy breakpoint. Author: MarkGo ---------------------------------------------------------------------------*/ DBG_API(BOOL) FDbgFalse() { return false; } #endif #ifdef __AFX_H__ /*!-------------------------------------------------------------------------- AfxAssertFailedLine Overrides Afx's assertion handling Author: GaryBu, kennt, MarkGo ---------------------------------------------------------------------------*/ BOOL AFXAPI AfxAssertFailedLine(LPCSTR lpszFileName, int nLine) { DbgAssert(lpszFileName, nLine, "AFX Assert"); return false; } #endif /*!-------------------------------------------------------------------------- DbgAssert Display assert dialog. Author: GaryBu, kennt, MarkGo ---------------------------------------------------------------------------*/ DBG_APIV(void) DbgAssert(LPCSTR szFile, int iLine, LPCSTR szFmt, ...) { va_list arg; char sz[MAX_PATH*2]; char *pch = sz; va_start(arg, szFmt); pch += wvsprintf(sz, szFmt, arg); va_end(arg); // Remove trailing newlines... while (*(pch-1) == '\n' || *(pch-1) == '\r') --pch; *pch = 0; if (g_dbi.fShowAsserts) { // // 03/27/96 cmason Added doing trace output as well as the Event Viewer // entry for asserts. // 04/04/96 cmason Removed redundancy of tracing out the assert twice, once // here and agian inside the SRVDBG code called by DoAssert. The code here // was first, but the the SRVDBG code traces out more events than just asserts. // DbgTrace( "Assert failed: "); // // This loggs to the Event Viewer // DoAssert(szFile, iLine, sz); // // 03/27/96 cmason Added breaking into the debugger if requested. // if( g_dbi.fStopOnAssert ) { // // This does a DebugBreak() and is protected by byt __try/__except so // that nothing happens if a debugger isn't running. // DbgStop(); } } else DbgTrace( "Skipped Assert (ShowAsserts is FALSE):\r\n%s (file %s, line %d)\r\n", sz, szFile, iLine); } /*!-------------------------------------------------------------------------- DbgStop -- causes a break into the debugger if the debugger is running. - Author: afx ---------------------------------------------------------------------------*/ #pragma optimize("qgel", off) // assembler cannot be globally optimized DBG_API(void) DbgStop() { __try { DebugBreak(); } __except (EXCEPTION_EXECUTE_HANDLER) { } } DBG_API(DWORD) DbgSetThreadTraceBuffer(DWORD itlsTrace) { DWORD itlsPrev = g_dbi.itlsTraceRGB; g_dbi.itlsTraceRGB = itlsTrace; return itlsPrev; } DBG_API(const char *) DbgGetTraceBuffer(BOOL fSecondChunk) { DbgTraceBuf *ptb; if (g_dbi.itlsTraceRGB == (DWORD)-1) return fSecondChunk ? "" : "\r\n"; if (NULL==(ptb = (DbgTraceBuf *)TlsGetValue(g_dbi.itlsTraceRGB))) return fSecondChunk ? "" : "\r\n"; if (!fSecondChunk) { // Return initial chunk, regardless of wraparound. return &(ptb->rgch[ptb->ichStart]); } // We only have a second chunk in wraparound if (ptb->ichStart > ptb->ichEnd) return ptb->rgch; return ""; } DBG_API(BOOL) DbgSetTraceBuffer(void *rgbTrace, int cbTrace) { DbgTraceBuf *ptb; if (g_dbi.itlsTraceRGB == (DWORD) -1 || (rgbTrace && cbTrace <= sizeof(DbgTraceBuf))) return false; ptb = (DbgTraceBuf *)rgbTrace; if (ptb) { ptb->cchBuf = cbTrace - sizeof(DbgTraceBuf); ptb->ichStart = ptb->ichEnd = 0; ptb->rgch[ptb->ichEnd] = '\0'; ptb->rgch[ptb->cchBuf] = '\0'; } TlsSetValue(g_dbi.itlsTraceRGB, ptb); return true; } #pragma optimize("", on) #endif //DEBUG /*********************************************************************** FUNCTION: LoadMsg Loads a string from the message table and returns it in an allocated string buffer. History Created on: 06/01/95 04/29/96 cmason Trav#336: Added FORMAT_MESSAGE_MAX_WIDTH_MASK so that CRLF's must be explicitly specified. ************************************************************************/ char *LoadMsg(UINT idMsg, HMODULE hmod) // May be null, in which case app's msg table is used { void *pv; char *pszRet; DWORD cch; cch = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, hmod, idMsg, 0 /*Default language*/, (char *)(&pv), 16, NULL); if ( !cch ) return NULL; // // 04/30/96 cmason #336: Removing the trailing space. // Assert( ' ' == ((char *)pv)[cch - 1]); ((char *)pv)[cch - 1] = '\0'; pszRet = new char[cch]; memcpy(pszRet, pv, cch); LocalFree(pv); return pszRet; }