windows-nt/Source/XPSP1/NT/printscan/fax/exchange/ab/debug.c
2020-09-26 16:20:57 +08:00

503 lines
14 KiB
C

// ----------------------------------------------------------------------------
// debug.c
//
// Microsoft At Work Fax Debugging Utilities
//
// Copyright (C) 1993 Microsoft Corporation
// ----------------------------------------------------------------------------
/* Revision History:
*
* When Who What
* -------- ------------------ ---------------------------------------
* 3.17.94 MAPI Original source from MAPI mapidbg.c
* 3.17.94 Yoram Yaacovi Modifications to overcome compobj.h problems
* 3.7.94 Yoram Yaacovi Update to MAPI build 154
* 12.1.94 Yoram Yaacovi Added DebugLog()
*
***********************************************************************/
#include <windows.h>
#include <stdio.h>
#include <time.h>
//#include "faxcfg.h"
#include "mapi.h"
#include "mapidbg.h"
#include "mapidefs.h"
#include "mapicode.h"
#ifdef DEBUG
/*
*
* From current\src\mapi\inc\_memcpy.h
*
* MemCopy()
*
* A much safer version of memcpy that checks the value of the byte
* count before calling the memcpy() function. This macro is only built
* into the 16 bit non-debug builds.
*/
#ifndef __MEMCPY_H_
#define __MEMCPY_H_
#define MemCopy(_dst,_src,_cb) memcpy(_dst,_src,(size_t)(_cb))
#endif
#if defined(WIN16) || defined(WIN32)
static BOOL fTraceEnabled = -1;
static BOOL fLogTraceEnabled = -1;
static BOOL fAssertLeaks = -1;
static TCHAR szKeyTraceEnabled[] = TEXT("DebugTrace");
static TCHAR szKeyLogTraceEnabled[] = TEXT("DebugTraceLog");
static TCHAR szKeyDebugTrap[] = TEXT("DebugTrap");
static TCHAR szKeyExtendedDebug[] = TEXT("ExtendedDebug");
static TCHAR szKeyUseVirtual[] = TEXT("VirtualMemory");
static TCHAR szKeyAssertLeaks[] = TEXT("AssertLeaks");
static TCHAR szKeyCheckOften[] = TEXT("CheckHeapOften");
static TCHAR szSectionDebug[] = TEXT("General");
static TCHAR szDebugIni[] = TEXT("MAWFDBG.INI");
#endif
// ExtendedDebug --------------------------------------------------------------
BOOL ExtendedDebug(void)
{
return (GetPrivateProfileInt(szSectionDebug, szKeyExtendedDebug,
0, szDebugIni));
}
// DebugTrap --------------------------------------------------------------
void DebugTrap(void)
{
if (GetPrivateProfileInt(szSectionDebug, szKeyDebugTrap,
0, szDebugIni))
DebugBreak();
}
// DebugLog --------------------------------------------------------------
void DebugLog(LPSTR szString)
{
FILE *logfile;
// open a log file for appending. create if does not exist
if ((logfile = fopen ("c:\\uilog.txt", "a+")) != NULL)
{
fwrite (szString, 1, strlen(szString), logfile);
fclose(logfile);
}
}
// DebugOutputFn --------------------------------------------------------------
void DebugOutputFn(char *psz)
{
#if defined(_MAC)
OutputDebugString(psz);
#else
char * pszBeg;
char * pszEnd;
char szBuf[3];
#if defined(WIN16) || defined(WIN32)
if (fTraceEnabled == -1)
{
fTraceEnabled = GetPrivateProfileInt(szSectionDebug, szKeyTraceEnabled,
0, szDebugIni);
}
if (!fTraceEnabled)
return;
if (fLogTraceEnabled == -1)
{
fLogTraceEnabled =
GetPrivateProfileInt(szSectionDebug, szKeyLogTraceEnabled, 0, szDebugIni);
}
#endif
for (pszBeg = psz; pszBeg && *pszBeg; pszBeg = pszEnd) {
pszEnd = strchr(pszBeg, '\n');
if (pszEnd) {
MemCopy(szBuf, pszEnd, 3);
if (pszEnd > pszBeg && *(pszEnd - 1) != '\r')
strcpy(pszEnd, "\r\n");
else
*(pszEnd + 1) = 0;
}
if (fLogTraceEnabled)
DebugLog(pszBeg);
else
OutputDebugStringA(pszBeg);
if (pszEnd) {
MemCopy(pszEnd, szBuf, 3);
pszEnd += 1;
}
}
#endif
}
// DebugTrapFn ----------------------------------------------------------------
#if defined(WIN32) && defined(THREAD_MSG_BOX)
typedef struct {
char * sz1;
char * sz2;
UINT rgf;
int iResult;
} MBContext;
DWORD WINAPI MessageBoxFnThreadMain(MBContext *pmbc)
{
pmbc->iResult = MessageBoxA(NULL, pmbc->sz1, pmbc->sz2,
pmbc->rgf | MB_SETFOREGROUND);
return(0);
}
int MessageBoxFn(char *sz1, char *sz2, UINT rgf)
{
HANDLE hThread;
DWORD dwThreadId;
MBContext mbc;
mbc.sz1 = sz1;
mbc.sz2 = sz2;
mbc.rgf = rgf;
mbc.iResult = IDRETRY;
hThread = CreateThread(NULL, 0,
(PTHREAD_START_ROUTINE)MessageBoxFnThreadMain, &mbc, 0, &dwThreadId);
if (hThread != NULL) {
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
}
return(mbc.iResult);
}
#else
#define MessageBoxFn(sz1, sz2, rgf) MessageBoxA(NULL, sz1, sz2, rgf)
#endif
int __cdecl DebugTrapFn(int fFatal, char *pszFile, int iLine, char *pszFormat, ...)
{
char sz[512];
va_list vl;
#if defined(WIN16) || defined(WIN32)
int id;
#endif
strcpy(sz, "++++ MAWF Debug Trap (");
_strdate(sz + strlen(sz));
strcat(sz, " ");
_strtime(sz + strlen(sz));
strcat(sz, ")\n");
DebugOutputFn(sz);
va_start(vl, pszFormat);
wvsprintfA(sz, pszFormat, vl);
va_end(vl);
wsprintfA(sz + strlen(sz), "\n[File %s, Line %d]\n\n", pszFile, iLine);
DebugOutputFn(sz);
#if defined(DOS)
_asm { int 3 }
#endif
#if defined(WIN16) || defined(WIN32)
// Hold down control key to prevent MessageBox
if ( GetAsyncKeyState(VK_CONTROL) >= 0 )
{
id = MessageBoxFn(sz, "Microsoft At Work Fax Debug Trap",
MB_ABORTRETRYIGNORE | MB_ICONHAND | MB_TASKMODAL |
(fFatal ? MB_DEFBUTTON1 : MB_DEFBUTTON3));
if (id == IDABORT)
*((LPBYTE)NULL) = 0;
else if (id == IDRETRY)
DebugBreak();
}
#endif
return(0);
}
// ExtendedDebugTraceFn ---------------------------------------------------------------
int __cdecl ExtendedDebugTraceFn(char *pszFormat, ...)
{
char sz[512];
int fAutoLF = 0;
va_list vl;
if (ExtendedDebug())
{
if (*pszFormat == '~') {
pszFormat += 1;
fAutoLF = 1;
}
va_start(vl, pszFormat);
wvsprintfA(sz, pszFormat, vl);
va_end(vl);
if (fAutoLF)
strcat(sz, "\n");
DebugOutputFn(sz);
}
return(0);
}
// DebugTraceFn ---------------------------------------------------------------
int __cdecl DebugTraceFn(char *pszFormat, ...)
{
char sz[512];
char sz1[512];
int fAutoLF = 0;
va_list vl;
HINSTANCE hInst=NULL; // this really needs to be a parameter
if (*pszFormat == '~') {
pszFormat += 1;
fAutoLF = 1;
}
va_start(vl, pszFormat);
wvsprintfA(sz, pszFormat, vl);
va_end(vl);
if (fAutoLF)
strcat(sz, "\n");
strcpy(sz1, sz);
DebugOutputFn(sz1);
return(0);
}
// SCODE & PropTag decoding ---------------------------------------------------
typedef struct
{
char * psz;
unsigned long ulPropTag;
} PT;
typedef struct
{
char * psz;
SCODE sc;
} SC;
#define Pt(_ptag) {#_ptag, _ptag}
#define Sc(_sc) {#_sc, _sc}
#if !defined(DOS)
static PT rgpt[] = {
/*
* Property types
*/
Pt(PT_UNSPECIFIED),
Pt(PT_NULL),
Pt(PT_I2),
Pt(PT_LONG),
Pt(PT_R4),
Pt(PT_DOUBLE),
Pt(PT_CURRENCY),
Pt(PT_APPTIME),
Pt(PT_ERROR),
Pt(PT_BOOLEAN),
Pt(PT_OBJECT),
Pt(PT_I8),
Pt(PT_STRING8),
Pt(PT_UNICODE),
Pt(PT_SYSTIME),
Pt(PT_CLSID),
Pt(PT_BINARY),
Pt(PT_TSTRING),
Pt(PT_MV_I2),
Pt(PT_MV_LONG),
Pt(PT_MV_R4),
Pt(PT_MV_DOUBLE),
Pt(PT_MV_CURRENCY),
Pt(PT_MV_APPTIME),
Pt(PT_MV_SYSTIME),
Pt(PT_MV_STRING8),
Pt(PT_MV_BINARY),
Pt(PT_MV_UNICODE),
Pt(PT_MV_CLSID),
Pt(PT_MV_I8)
};
#define cpt (sizeof(rgpt) / sizeof(PT))
static SC rgsc[] = {
/* FACILITY_NULL error codes from OLE */
Sc(S_OK),
Sc(S_FALSE),
Sc(E_UNEXPECTED),
Sc(E_NOTIMPL),
Sc(E_OUTOFMEMORY),
Sc(E_INVALIDARG),
Sc(E_NOINTERFACE),
Sc(E_POINTER),
Sc(E_HANDLE),
Sc(E_ABORT),
Sc(E_FAIL),
Sc(E_ACCESSDENIED),
/* General errors (used by more than one MAPI object) */
Sc(MAPI_E_NO_SUPPORT),
Sc(MAPI_E_BAD_CHARWIDTH),
Sc(MAPI_E_STRING_TOO_LONG),
Sc(MAPI_E_UNKNOWN_FLAGS),
Sc(MAPI_E_INVALID_ENTRYID),
Sc(MAPI_E_INVALID_OBJECT),
Sc(MAPI_E_OBJECT_CHANGED),
Sc(MAPI_E_OBJECT_DELETED),
Sc(MAPI_E_BUSY),
Sc(MAPI_E_NOT_ENOUGH_DISK),
Sc(MAPI_E_NOT_ENOUGH_RESOURCES),
Sc(MAPI_E_NOT_FOUND),
Sc(MAPI_E_VERSION),
Sc(MAPI_E_LOGON_FAILED),
Sc(MAPI_E_SESSION_LIMIT),
Sc(MAPI_E_USER_CANCEL),
Sc(MAPI_E_UNABLE_TO_ABORT),
Sc(MAPI_E_NETWORK_ERROR),
Sc(MAPI_E_DISK_ERROR),
Sc(MAPI_E_TOO_COMPLEX),
Sc(MAPI_E_BAD_COLUMN),
Sc(MAPI_E_EXTENDED_ERROR),
Sc(MAPI_E_COMPUTED),
/* MAPI base function and status object specific errors and warnings */
Sc(MAPI_E_END_OF_SESSION),
Sc(MAPI_E_UNKNOWN_ENTRYID),
Sc(MAPI_E_MISSING_REQUIRED_COLUMN),
/* Property specific errors and warnings */
Sc(MAPI_E_BAD_VALUE),
Sc(MAPI_E_INVALID_TYPE),
Sc(MAPI_E_TYPE_NO_SUPPORT),
Sc(MAPI_E_UNEXPECTED_TYPE),
Sc(MAPI_E_TOO_BIG),
Sc(MAPI_W_ERRORS_RETURNED),
/* Table specific errors and warnings */
Sc(MAPI_E_UNABLE_TO_COMPLETE),
Sc(MAPI_E_TABLE_EMPTY),
Sc(MAPI_E_TABLE_TOO_BIG),
Sc(MAPI_E_INVALID_BOOKMARK),
Sc(MAPI_W_POSITION_CHANGED),
Sc(MAPI_W_APPROX_COUNT),
/* Transport specific errors and warnings */
Sc(MAPI_E_WAIT),
Sc(MAPI_E_CANCEL),
Sc(MAPI_E_NOT_ME),
Sc(MAPI_W_CANCEL_MESSAGE),
/* Message Store, Folder, and Message specific errors and warnings */
Sc(MAPI_E_CORRUPT_STORE),
Sc(MAPI_E_NOT_IN_QUEUE),
Sc(MAPI_E_NO_SUPPRESS),
Sc(MAPI_E_COLLISION),
Sc(MAPI_E_NOT_INITIALIZED),
Sc(MAPI_E_NON_STANDARD),
Sc(MAPI_E_NO_RECIPIENTS),
Sc(MAPI_E_SUBMITTED),
Sc(MAPI_E_HAS_FOLDERS),
Sc(MAPI_E_HAS_MESSAGES),
Sc(MAPI_E_FOLDER_CYCLE),
/* Address Book specific errors and warnings */
Sc(MAPI_E_AMBIGUOUS_RECIP)
};
#define csc (sizeof(rgsc) / sizeof(SC))
#endif
char * __cdecl
SzDecodeScodeFn(SCODE sc)
{
static char rgch[64];
#if !defined(DOS)
int isc;
for (isc = 0; isc < csc; ++isc)
if (sc == rgsc[isc].sc)
return rgsc[isc].psz;
#endif
wsprintfA (rgch, "%08lX", sc);
return rgch;
}
#else // no DEBUG
typedef long SCODE;
// need to define empty functions for DEF file resolution
BOOL ExtendedDebug(void)
{
return FALSE;
}
void DebugTrap(void)
{
}
int __cdecl DebugTrapFn(int fFatal, char *pszFile, int iLine, char *pszFormat, ...)
{
return 0;
}
int __cdecl DebugTraceFn(char *pszFormat, ...)
{
return 0;
}
int __cdecl ExtendedDebugTraceFn(char *pszFormat, ...)
{
return 0;
}
char * __cdecl SzDecodeScodeFn(SCODE sc)
{
return NULL;
}
#endif