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.
673 lines
16 KiB
673 lines
16 KiB
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
|
|
//
|
|
// Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
|
|
//
|
|
// Other brand and product names used herein are trademarks of their respective owners.
|
|
//
|
|
// The entire program and user interface including the structure, sequence, selection,
|
|
// and arrangement of the dialog, the exclusively "yes" and "no" choices represented
|
|
// by "1" and "2," and each dialog message are protected by copyrights registered in
|
|
// the United States and by international treaties.
|
|
//
|
|
// Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
|
|
// 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
|
|
//
|
|
// Active Voice Corporation
|
|
// Seattle, Washington
|
|
// USA
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////
|
|
// trace.c - debug trace functions
|
|
////
|
|
|
|
#ifndef NOTRACE
|
|
|
|
#include "winlocal.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
|
|
#include "trace.h"
|
|
#include "mem.h"
|
|
#include "sys.h"
|
|
#include "str.h"
|
|
|
|
////
|
|
// private definitions
|
|
////
|
|
|
|
// wOutputTo values
|
|
//
|
|
#define TRACE_OUTPUTNONE 0x0000
|
|
#define TRACE_OUTPUTDEBUGSTRING 0x0001
|
|
#define TRACE_OUTPUTCOMM 0x0002
|
|
#if 0 // no longer supported
|
|
#define TRACE_OUTPUTFILE 0x0004
|
|
#endif
|
|
#ifdef _WIN32
|
|
#define TRACE_OUTPUTCONSOLE 0x0008
|
|
#endif
|
|
|
|
// trace control struct
|
|
//
|
|
typedef struct TRACE
|
|
{
|
|
DWORD dwVersion;
|
|
HINSTANCE hInst;
|
|
HTASK hTask;
|
|
int nLevel;
|
|
int wOutputTo;
|
|
#ifdef TRACE_OUTPUTFILE
|
|
HFIL hFile;
|
|
#endif
|
|
#ifdef _WIN32
|
|
HANDLE hConsole;
|
|
#endif
|
|
int hComm;
|
|
LPTSTR lpszTemp;
|
|
} TRACE, FAR *LPTRACE;
|
|
|
|
// shared trace engine handle
|
|
//
|
|
static LPTRACE lpTraceShare = NULL;
|
|
static int cShareUsage = 0;
|
|
|
|
#define TRACE_SECTION TEXT("TRACE")
|
|
#define TRACE_PROFILE TraceGetProfile()
|
|
|
|
// helper functions
|
|
//
|
|
static LPTRACE TraceGetPtr(HTRACE hTrace);
|
|
static HTRACE TraceGetHandle(LPTRACE lpTrace);
|
|
static int TraceError(LPCTSTR lpszFormat, ...);
|
|
static LPTSTR TraceGetProfile(void);
|
|
|
|
////
|
|
// public functions
|
|
////
|
|
|
|
// TraceInit - initialize trace engine
|
|
// <dwVersion> (i) must be TRACE_VERSION
|
|
// <hInst> (i) instance of calling module
|
|
// return handle to trace engine (NULL if error)
|
|
//
|
|
// NOTE: The level and destination of trace output is determined
|
|
// by values found in the file TRACE.INI in the Windows directory.
|
|
// TRACE.INI is expected to have the following format:
|
|
//
|
|
// [TRACE]
|
|
// Level=0 {TRACE_MINLEVEL...TRACE_MAXLEVEL}
|
|
// OutputTo= OutputDebugString()
|
|
// =COM1 COM1:9600,n,8,1
|
|
// =COM2:2400,n,8,1 specified comm device
|
|
// =filename specified file
|
|
#ifdef _WIN32
|
|
// =console stdout
|
|
#endif
|
|
//
|
|
HTRACE DLLEXPORT WINAPI TraceInit(DWORD dwVersion, HINSTANCE hInst)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPTRACE lpTrace = NULL;
|
|
TCHAR szOutputTo[_MAX_PATH];
|
|
#ifdef _WIN32
|
|
BOOL fShare = TRUE; // FALSE;
|
|
#else
|
|
BOOL fShare = TRUE;
|
|
#endif
|
|
int nLevel = -1;
|
|
LPTSTR lpszOutputTo = NULL;
|
|
|
|
if (dwVersion != TRACE_VERSION)
|
|
fSuccess = FALSE;
|
|
|
|
else if (hInst == NULL)
|
|
fSuccess = FALSE;
|
|
|
|
else if (nLevel != -1 &&
|
|
(nLevel < TRACE_MINLEVEL || nLevel > TRACE_MAXLEVEL))
|
|
fSuccess = FALSE;
|
|
|
|
// if a shared trace engine already exists,
|
|
// use it rather than create another one
|
|
//
|
|
else if (fShare && cShareUsage > 0 && lpTraceShare != NULL)
|
|
lpTrace = lpTraceShare;
|
|
|
|
#if 0 // can't call mem functions, because they require trace functions
|
|
else if ((lpTrace = (LPTRACE) MemAlloc(NULL, sizeof(TRACE), 0)) == NULL)
|
|
#else
|
|
#ifdef _WIN32
|
|
else if ((lpTrace = (LPTRACE) HeapAlloc(GetProcessHeap(),
|
|
HEAP_ZERO_MEMORY, sizeof(TRACE))) == NULL)
|
|
#else
|
|
else if ((lpTrace = (LPTRACE) GlobalAllocPtr(GMEM_MOVEABLE |
|
|
GMEM_ZEROINIT, sizeof(TRACE))) == NULL)
|
|
#endif
|
|
#endif
|
|
fSuccess = FALSE;
|
|
|
|
else
|
|
{
|
|
lpTrace->dwVersion = dwVersion;
|
|
lpTrace->hInst = hInst;
|
|
lpTrace->hTask = GetCurrentTask();
|
|
lpTrace->nLevel = nLevel != -1 ? nLevel :
|
|
GetPrivateProfileInt(TRACE_SECTION, TEXT("Level"), 0, TRACE_PROFILE);
|
|
lpTrace->wOutputTo = TRACE_OUTPUTNONE;
|
|
#ifdef TRACE_OUTPUTFILE
|
|
lpTrace->hFile = NULL;
|
|
#endif
|
|
#ifdef _WIN32
|
|
lpTrace->hConsole = NULL;
|
|
#endif
|
|
lpTrace->hComm = -1;
|
|
lpTrace->lpszTemp = NULL;
|
|
|
|
// use the specified destination if possible
|
|
//
|
|
if (lpszOutputTo != NULL)
|
|
StrNCpy(szOutputTo, lpszOutputTo, SIZEOFARRAY(szOutputTo));
|
|
|
|
// else use the last known destination
|
|
//
|
|
else
|
|
{
|
|
GetPrivateProfileString(TRACE_SECTION, TEXT("OutputTo"), TEXT(""),
|
|
szOutputTo, SIZEOFARRAY(szOutputTo), TRACE_PROFILE);
|
|
}
|
|
|
|
// use OutputDebugString() if destination == ""
|
|
//
|
|
if (*szOutputTo == '\0')
|
|
lpTrace->wOutputTo = TRACE_OUTPUTDEBUGSTRING;
|
|
|
|
// use standard output console if specified
|
|
//
|
|
else if (StrICmp(szOutputTo, TEXT("Console")) == 0)
|
|
{
|
|
#ifdef _WIN32
|
|
COORD coord;
|
|
|
|
lpTrace->wOutputTo = TRACE_OUTPUTCONSOLE;
|
|
|
|
AllocConsole();
|
|
lpTrace->hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
|
|
coord.X = 80;
|
|
coord.Y = 1000;
|
|
SetConsoleScreenBufferSize(lpTrace->hConsole, coord);
|
|
#else
|
|
lpTrace->wOutputTo = TRACE_OUTPUTDEBUGSTRING;
|
|
#endif
|
|
}
|
|
|
|
// use serial comm device if destination starts with "COMx"
|
|
//
|
|
else if (StrNICmp(szOutputTo, TEXT("COM"), 3) == 0 &&
|
|
ChrIsDigit(*(szOutputTo + 3)))
|
|
{
|
|
// Comm functions not available under WIN32
|
|
//
|
|
#ifdef _WIN32
|
|
lpTrace->wOutputTo = TRACE_OUTPUTDEBUGSTRING;
|
|
#else
|
|
TCHAR szComX[16];
|
|
DCB dcb;
|
|
int iError;
|
|
|
|
StrNCpy(szComX, szOutputTo, 5);
|
|
*(szComX + 5) = '\0';
|
|
|
|
// convert "COM1" to "COM1:"
|
|
//
|
|
if (*(szOutputTo + 4) == '\0')
|
|
StrCat(szOutputTo, TEXT(":"));
|
|
|
|
// convert "COM1:" to "COM1:9600,n,8,1"
|
|
//
|
|
if (*(szOutputTo + 5) == '\0')
|
|
StrCat(szOutputTo, TEXT("9600,n,8,1"));
|
|
|
|
// [From the WinSDK KnowledgeBase PSS ID Number: Q102642]
|
|
// The cbInQueue and cbOutQueue parameters of OpenComm() are
|
|
// both type UINT and should be valid up to 64K. However,
|
|
// values greater than or equal to 32K cause strange behavior.
|
|
//
|
|
if ((lpTrace->hComm = OpenComm(szComX, 1024, 32767)) < 0)
|
|
{
|
|
TraceError(TEXT("OpenComm error (%d)\n"), lpTrace->hComm);
|
|
lpTrace->hComm = -1;
|
|
fSuccess = FALSE;
|
|
}
|
|
|
|
else if ((iError = BuildCommDCB(szOutputTo, &dcb)) != 0)
|
|
{
|
|
TraceError(TEXT("BuildCommDCB error (%d)\n"), iError);
|
|
fSuccess = FALSE;
|
|
}
|
|
|
|
else if ((iError = SetCommState(&dcb)) != 0)
|
|
{
|
|
TraceError(TEXT("SetCommState error (%d)\n"), iError);
|
|
fSuccess = FALSE;
|
|
}
|
|
|
|
else
|
|
lpTrace->wOutputTo = TRACE_OUTPUTCOMM;
|
|
#endif
|
|
}
|
|
|
|
#ifdef TRACE_OUTPUTFILE
|
|
// else assume the string must be a file name
|
|
//
|
|
else
|
|
{
|
|
if ((lpTrace->hFile = FileCreate(szOutputTo, 0, !fShare)) == NULL)
|
|
{
|
|
TraceError(TEXT("FileCreate error (%s)\n"), (LPTSTR) szOutputTo);
|
|
fSuccess = FALSE;
|
|
}
|
|
|
|
else
|
|
lpTrace->wOutputTo = TRACE_OUTPUTFILE;
|
|
}
|
|
#else
|
|
else
|
|
{
|
|
TraceError(TEXT("Unknown trace OutputTo (%s)\n"), (LPTSTR) szOutputTo);
|
|
fSuccess = FALSE;
|
|
}
|
|
#endif
|
|
|
|
if (fSuccess &&
|
|
#if 0 // can't call mem functions, because they require trace functions
|
|
(lpTrace->lpszTemp = (LPTSTR) MemAlloc(NULL,
|
|
1024 * sizeof(TCHAR), 0)) == NULL)
|
|
#else
|
|
#ifdef _WIN32
|
|
(lpTrace->lpszTemp = (LPTSTR) HeapAlloc(GetProcessHeap(),
|
|
HEAP_ZERO_MEMORY, 1024 * sizeof(TCHAR))) == NULL)
|
|
#else
|
|
(lpTrace->lpszTemp = (LPTSTR) GlobalAllocPtr(
|
|
GMEM_MOVEABLE | GMEM_ZEROINIT, 1024 * sizeof(TCHAR))) == NULL)
|
|
#endif
|
|
#endif
|
|
fSuccess = FALSE;
|
|
}
|
|
|
|
if (!fSuccess)
|
|
{
|
|
TraceTerm(TraceGetHandle(lpTrace));
|
|
lpTrace = NULL;
|
|
}
|
|
|
|
// keep track of total modules sharing a task engine handle
|
|
//
|
|
if (fSuccess && fShare)
|
|
{
|
|
if (++cShareUsage == 1)
|
|
lpTraceShare = lpTrace;
|
|
}
|
|
|
|
return fSuccess ? TraceGetHandle(lpTrace) : NULL;
|
|
}
|
|
|
|
// TraceTerm - shut down trace engine
|
|
// <hTrace> (i) handle returned from TraceInit or NULL
|
|
// return 0 if success
|
|
//
|
|
int DLLEXPORT WINAPI TraceTerm(HTRACE hTrace)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPTRACE lpTrace;
|
|
|
|
if ((lpTrace = TraceGetPtr(hTrace)) == NULL)
|
|
fSuccess = FALSE;
|
|
|
|
// only shut down trace engine if handle
|
|
// is not shared (or is no longer being shared)
|
|
//
|
|
else if (lpTrace != lpTraceShare || --cShareUsage <= 0)
|
|
{
|
|
#ifndef _WIN32
|
|
int iError;
|
|
#endif
|
|
// shared trace engine handle no longer valid
|
|
//
|
|
if (cShareUsage <= 0)
|
|
lpTraceShare = NULL;
|
|
|
|
// Comm functions not available under WIN32
|
|
//
|
|
#ifndef _WIN32
|
|
if (lpTrace->hComm != -1 &&
|
|
(iError = CloseComm(lpTrace->hComm)) != 0)
|
|
{
|
|
TraceError(TEXT("CloseComm error (%d)\n"), iError);
|
|
fSuccess = FALSE;
|
|
}
|
|
else
|
|
lpTrace->hComm = -1;
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
if (lpTrace->hConsole != NULL)
|
|
{
|
|
FreeConsole();
|
|
lpTrace->hConsole = NULL;
|
|
}
|
|
#endif
|
|
|
|
#ifdef TRACE_OUTPUTFILE
|
|
if (lpTrace->hFile != NULL &&
|
|
FileClose(lpTrace->hFile) != 0)
|
|
{
|
|
TraceError(TEXT("FileClose error\n"));
|
|
fSuccess = FALSE;
|
|
}
|
|
else
|
|
lpTrace->hFile = NULL;
|
|
#endif
|
|
|
|
if (lpTrace->lpszTemp != NULL &&
|
|
#if 0 // can't call mem functions, because they require trace functions
|
|
(lpTrace->lpszTemp = MemFree(NULL, lpTrace->lpszTemp)) != NULL)
|
|
#else
|
|
#ifdef _WIN32
|
|
(!HeapFree(GetProcessHeap(), 0, lpTrace->lpszTemp)))
|
|
#else
|
|
(GlobalFreePtr(lpTrace->lpszTemp) != 0))
|
|
#endif
|
|
#endif
|
|
fSuccess = FALSE;
|
|
|
|
lpTrace->wOutputTo = TRACE_OUTPUTNONE;
|
|
|
|
#if 0 // can't call mem functions, because they require trace functions
|
|
if ((lpTrace = MemFree(NULL, lpTrace)) != NULL)
|
|
#else
|
|
#ifdef _WIN32
|
|
if (!HeapFree(GetProcessHeap(), 0, lpTrace->lpszTemp))
|
|
#else
|
|
if (GlobalFreePtr(lpTrace->lpszTemp) != 0)
|
|
#endif
|
|
#endif
|
|
fSuccess = FALSE;
|
|
}
|
|
|
|
return fSuccess ? 0 : -1;
|
|
}
|
|
|
|
// TraceGetLevel - get current trace level
|
|
// <hTrace> (i) handle returned from TraceInit or NULL
|
|
// return trace level (-1 if error)
|
|
//
|
|
int DLLEXPORT WINAPI TraceGetLevel(HTRACE hTrace)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPTRACE lpTrace;
|
|
|
|
if ((lpTrace = TraceGetPtr(hTrace)) == NULL)
|
|
fSuccess = FALSE;
|
|
|
|
return fSuccess ? lpTrace->nLevel : -1;
|
|
}
|
|
|
|
// TraceSetLevel - set new trace level (-1 if error)
|
|
// <hTrace> (i) handle returned from TraceInit or NULL
|
|
// <nLevel> (i) new trace level {TRACE_MINLEVEL...TRACE_MAXLEVEL}
|
|
// return 0 if success
|
|
//
|
|
int DLLEXPORT WINAPI TraceSetLevel(HTRACE hTrace, int nLevel)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPTRACE lpTrace;
|
|
|
|
if ((lpTrace = TraceGetPtr(hTrace)) == NULL)
|
|
fSuccess = FALSE;
|
|
|
|
else if (nLevel < TRACE_MINLEVEL || nLevel > TRACE_MAXLEVEL)
|
|
fSuccess = FALSE;
|
|
|
|
else
|
|
{
|
|
TCHAR szLevel[17];
|
|
|
|
lpTrace->nLevel = nLevel;
|
|
|
|
// save the level for next time
|
|
//
|
|
StrItoA(lpTrace->nLevel, szLevel, 10);
|
|
WritePrivateProfileString(TRACE_SECTION, TEXT("Level"), szLevel, TRACE_PROFILE);
|
|
|
|
// display new trace level whenever it changes
|
|
//
|
|
TracePrintf_1(hTrace, 1, TEXT("TraceLevel=%d\n"),
|
|
(int) lpTrace->nLevel);
|
|
}
|
|
|
|
return fSuccess ? 0 : -1;
|
|
}
|
|
|
|
// TraceOutput - output debug string
|
|
// <hTrace> (i) handle returned from TraceInit or NULL
|
|
// <nLevel> (i) output only if current trace level is >= nLevel
|
|
// <lpszText> (i) string to output
|
|
// return 0 if success
|
|
//
|
|
int DLLEXPORT WINAPI TraceOutput(HTRACE hTrace, int nLevel, LPCTSTR lpszText)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPTRACE lpTrace;
|
|
|
|
if ((lpTrace = TraceGetPtr(hTrace)) == NULL)
|
|
fSuccess = FALSE;
|
|
|
|
else if (lpszText == NULL)
|
|
fSuccess = FALSE;
|
|
|
|
else if (nLevel > 0 && nLevel <= lpTrace->nLevel)
|
|
{
|
|
switch (lpTrace->wOutputTo)
|
|
{
|
|
case TRACE_OUTPUTNONE:
|
|
break;
|
|
|
|
case TRACE_OUTPUTDEBUGSTRING:
|
|
OutputDebugString(lpszText);
|
|
break;
|
|
#ifdef _WIN32
|
|
case TRACE_OUTPUTCONSOLE:
|
|
if (lpTrace->hConsole != NULL)
|
|
{
|
|
DWORD dwBytes;
|
|
WriteFile(lpTrace->hConsole, lpszText, StrLen(lpszText), &dwBytes, NULL);
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
case TRACE_OUTPUTCOMM:
|
|
// Comm functions not available under WIN32
|
|
//
|
|
#ifdef _WIN32
|
|
OutputDebugString(lpszText);
|
|
#else
|
|
if (lpTrace->hComm != -1)
|
|
{
|
|
LPCTSTR lpsz;
|
|
TCHAR chReturn = '\r';
|
|
|
|
for (lpsz = lpszText; *lpsz != '\0'; lpsz = StrNextChr(lpsz))
|
|
{
|
|
if ((*lpsz == '\n' &&
|
|
WriteComm(lpTrace->hComm, &chReturn, 1) < 0) ||
|
|
WriteComm(lpTrace->hComm, lpsz, 1) <= 0)
|
|
{
|
|
COMSTAT comstat;
|
|
GetCommError(lpTrace->hComm, &comstat);
|
|
TraceError(TEXT("WriteComm error (%u, %u, %u) %s\n"),
|
|
(UINT) comstat.status,
|
|
(UINT) comstat.cbInQue,
|
|
(UINT) comstat.cbOutQue,
|
|
(LPTSTR) lpszText);
|
|
fSuccess = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
#ifdef TRACE_OUTPUTFILE
|
|
case TRACE_OUTPUTFILE:
|
|
if (lpTrace->hFile != NULL)
|
|
{
|
|
LPCTSTR lpsz;
|
|
TCHAR chReturn = '\r';
|
|
|
|
for (lpsz = lpszText; *lpsz != '\0'; lpsz = StrNextChr(lpsz))
|
|
{
|
|
if ((*lpsz == '\n' &&
|
|
FileWrite(lpTrace->hFile, &chReturn, 1) == -1) ||
|
|
FileWrite(lpTrace->hFile, lpsz, 1) == -1)
|
|
{
|
|
TraceError(TEXT("FileWrite error: %s\n"),
|
|
(LPTSTR) lpszText);
|
|
fSuccess = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return fSuccess ? 0 : -1;
|
|
}
|
|
|
|
// TracePrintf - output formatted debug string
|
|
// <hTrace> (i) handle returned from TraceInit or NULL
|
|
// <nLevel> (i) output only if current trace level is >= nLevel
|
|
// <lpszFormat,...> (i) format string and arguments to output
|
|
// return 0 if success
|
|
//
|
|
int DLLEXPORT FAR CDECL TracePrintf(HTRACE hTrace, int nLevel, LPCTSTR lpszFormat, ...)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPTRACE lpTrace;
|
|
|
|
if ((lpTrace = TraceGetPtr(hTrace)) == NULL)
|
|
fSuccess = FALSE;
|
|
|
|
else if (nLevel <= lpTrace->nLevel)
|
|
{
|
|
va_list args;
|
|
|
|
va_start(args, lpszFormat);
|
|
wvsprintf(lpTrace->lpszTemp, lpszFormat, args);
|
|
va_end(args);
|
|
|
|
if (TraceOutput(hTrace, nLevel, lpTrace->lpszTemp) != 0)
|
|
fSuccess = FALSE;
|
|
}
|
|
|
|
return fSuccess ? 0 : -1;
|
|
}
|
|
|
|
////
|
|
// private functions
|
|
////
|
|
|
|
// TraceGetPtr - convert trace handle to trace pointer
|
|
// <hTrace> (i) handle returned from TraceInit or NULL
|
|
// return trace pointer (NULL if error)
|
|
//
|
|
static LPTRACE TraceGetPtr(HTRACE hTrace)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPTRACE lpTrace;
|
|
|
|
// use shared trace handle if no other supplied
|
|
//
|
|
if (hTrace == NULL && lpTraceShare != NULL)
|
|
lpTrace = lpTraceShare;
|
|
|
|
// create shared trace handle if no other supplied
|
|
//
|
|
else if (hTrace == NULL && lpTraceShare == NULL &&
|
|
(hTrace = TraceInit(TRACE_VERSION, SysGetTaskInstance(NULL))) == NULL)
|
|
fSuccess = FALSE;
|
|
|
|
else if ((lpTrace = (LPTRACE) hTrace) == NULL)
|
|
fSuccess = FALSE;
|
|
|
|
// note: check for good pointer made only if not using lpTraceShare
|
|
//
|
|
else if (lpTrace != lpTraceShare &&
|
|
IsBadWritePtr(lpTrace, sizeof(TRACE)))
|
|
fSuccess = FALSE;
|
|
|
|
#ifdef CHECKTASK
|
|
// make sure current task owns the trace handle
|
|
// except when shared trace handle is used
|
|
//
|
|
if (fSuccess && lpTrace != lpTraceShare &&
|
|
lpTrace->hTask != GetCurrentTask())
|
|
fSuccess = FALSE;
|
|
#endif
|
|
|
|
return fSuccess ? lpTrace : NULL;
|
|
}
|
|
|
|
// TraceGetHandle - convert trace pointer to trace handle
|
|
// <lpTrace> (i) pointer to TRACE struct
|
|
// return trace handle (NULL if error)
|
|
//
|
|
static HTRACE TraceGetHandle(LPTRACE lpTrace)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
HTRACE hTrace;
|
|
|
|
if ((hTrace = (HTRACE) lpTrace) == NULL)
|
|
fSuccess = FALSE;
|
|
|
|
return fSuccess ? hTrace : NULL;
|
|
}
|
|
|
|
// TraceError - display formatted trace error string
|
|
// <lpszFormat...> (i) format string and arguments to output
|
|
// return 0 if success
|
|
//
|
|
static int TraceError(LPCTSTR lpszFormat, ...)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
va_list args;
|
|
TCHAR lpszTemp[256];
|
|
|
|
va_start(args, lpszFormat);
|
|
wvsprintf(lpszTemp, lpszFormat, args);
|
|
va_end(args);
|
|
|
|
OutputDebugString(lpszTemp);
|
|
|
|
return fSuccess ? 0 : -1;
|
|
}
|
|
|
|
// TraceGetProfile - get trace ini file name
|
|
// return pointer to file name
|
|
//
|
|
static LPTSTR TraceGetProfile(void)
|
|
{
|
|
return TEXT("trace.ini");
|
|
}
|
|
|
|
#endif // #ifndef NOTRACE
|