|
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
//
// MODULE: TapiInfo.c
//
// PURPOSE: Handles all Pretty Printing functions for the TapiComm sample.
//
// EXPORTED FUNCTIONS: These functions are for use by other modules.
//
// All of these pretty print to the debugging output.
// OutputDebugLineCallback - Calls FormatLineCallback.
// OutputDebugLineError - Calls OutputDebugLineErrorFileLine.
// OutputDebugLastError - Calls OutputDebugLineErrorFileLine.
// OutputDebugPrintf - Calls wsprintf
// OutputDebugLineErrorFileLine - Calls FormatLineError
// OutputDebugLastErrorFileLine - Calls FormatLastError
//
// All of these functions pretty print to a string buffer.
// FormatLineError - Prints a LINEERR
// FormatLastError - Prints a GetLastError error.
// FormatLineCallback - Prints a lineCallbackFunc message.
//
// INTERNAL FUNCTION: These functions are for this module only.
// strBinaryArrayAppend - prints a binary flag array to a buffer.
#include <windows.h>
#include <tapi.h>
#include "TapiInfo.h"
// Maximum length of all internal string buffers.
#define MAXOUTPUTSTRINGLENGTH 4096
// define to make accessing arrays easy.
#define sizeofArray(pArray) (sizeof(pArray) / sizeof((pArray)[0]))
//*****************************************
// Internal prototypes.
//*****************************************
static long strBinaryArrayAppend(LPSTR pszOutputBuffer, DWORD dwFlags, LPSTR szStringArray[], DWORD dwSizeofStringArray);
//*****************************************
// Global arrays for interpreting TAPI constants.
//*****************************************
LPSTR pszLineErrorNameArray[] = { "", "LINEERR_ALLOCATED", "LINEERR_BADDEVICEID", "LINEERR_BEARERMODEUNAVAIL", "LINEERR Unused constant, ERROR!!", "LINEERR_CALLUNAVAIL", "LINEERR_COMPLETIONOVERRUN", "LINEERR_CONFERENCEFULL", "LINEERR_DIALBILLING", "LINEERR_DIALDIALTONE", "LINEERR_DIALPROMPT", "LINEERR_DIALQUIET", "LINEERR_INCOMPATIBLEAPIVERSION", "LINEERR_INCOMPATIBLEEXTVERSION", "LINEERR_INIFILECORRUPT", "LINEERR_INUSE", "LINEERR_INVALADDRESS", "LINEERR_INVALADDRESSID", "LINEERR_INVALADDRESSMODE", "LINEERR_INVALADDRESSSTATE", "LINEERR_INVALAPPHANDLE", "LINEERR_INVALAPPNAME", "LINEERR_INVALBEARERMODE", "LINEERR_INVALCALLCOMPLMODE", "LINEERR_INVALCALLHANDLE", "LINEERR_INVALCALLPARAMS", "LINEERR_INVALCALLPRIVILEGE", "LINEERR_INVALCALLSELECT", "LINEERR_INVALCALLSTATE", "LINEERR_INVALCALLSTATELIST", "LINEERR_INVALCARD", "LINEERR_INVALCOMPLETIONID", "LINEERR_INVALCONFCALLHANDLE", "LINEERR_INVALCONSULTCALLHANDLE", "LINEERR_INVALCOUNTRYCODE", "LINEERR_INVALDEVICECLASS", "LINEERR_INVALDEVICEHANDLE", "LINEERR_INVALDIALPARAMS", "LINEERR_INVALDIGITLIST", "LINEERR_INVALDIGITMODE", "LINEERR_INVALDIGITS", "LINEERR_INVALEXTVERSION", "LINEERR_INVALGROUPID", "LINEERR_INVALLINEHANDLE", "LINEERR_INVALLINESTATE", "LINEERR_INVALLOCATION", "LINEERR_INVALMEDIALIST", "LINEERR_INVALMEDIAMODE", "LINEERR_INVALMESSAGEID", "LINEERR Unused constant, ERROR!!", "LINEERR_INVALPARAM", "LINEERR_INVALPARKID", "LINEERR_INVALPARKMODE", "LINEERR_INVALPOINTER", "LINEERR_INVALPRIVSELECT", "LINEERR_INVALRATE", "LINEERR_INVALREQUESTMODE", "LINEERR_INVALTERMINALID", "LINEERR_INVALTERMINALMODE", "LINEERR_INVALTIMEOUT", "LINEERR_INVALTONE", "LINEERR_INVALTONELIST", "LINEERR_INVALTONEMODE", "LINEERR_INVALTRANSFERMODE", "LINEERR_LINEMAPPERFAILED", "LINEERR_NOCONFERENCE", "LINEERR_NODEVICE", "LINEERR_NODRIVER", "LINEERR_NOMEM", "LINEERR_NOREQUEST", "LINEERR_NOTOWNER", "LINEERR_NOTREGISTERED", "LINEERR_OPERATIONFAILED", "LINEERR_OPERATIONUNAVAIL", "LINEERR_RATEUNAVAIL", "LINEERR_RESOURCEUNAVAIL", "LINEERR_REQUESTOVERRUN", "LINEERR_STRUCTURETOOSMALL", "LINEERR_TARGETNOTFOUND", "LINEERR_TARGETSELF", "LINEERR_UNINITIALIZED", "LINEERR_USERUSERINFOTOOBIG", "LINEERR_REINIT", "LINEERR_ADDRESSBLOCKED", "LINEERR_BILLINGREJECTED", "LINEERR_INVALFEATURE", "LINEERR_NOMULTIPLEINSTANCE" };
LPSTR psz_dwMsg[] = { "LINE_ADDRESSSTATE", "LINE_CALLINFO", "LINE_CALLSTATE", "LINE_CLOSE", "LINE_DEVSPECIFIC", "LINE_DEVSPECIFICFEATURE", "LINE_GATHERDIGITS", "LINE_GENERATE", "LINE_LINEDEVSTATE", "LINE_MONITORDIGITS", "LINE_MONITORMEDIA", "LINE_MONITORTONE", "LINE_REPLY", "LINE_REQUEST", "PHONE_BUTTON", "PHONE_CLOSE", "PHONE_DEVSPECIFIC", "PHONE_REPLY", "PHONE_STATE", "LINE_CREATE", "PHONE_CREATE" };
LPSTR pszfLINEADDRESSSTATE[] = { "Unknown LINEADDRESSSTATE information", "LINEADDRESSSTATE_OTHER", "LINEADDRESSSTATE_DEVSPECIFIC", "LINEADDRESSSTATE_INUSEZERO", "LINEADDRESSSTATE_INUSEONE", "LINEADDRESSSTATE_INUSEMANY", "LINEADDRESSSTATE_NUMCALLS", "LINEADDRESSSTATE_FORWARD", "LINEADDRESSSTATE_TERMINALS", "LINEADDRESSSTATE_CAPSCHANGE" };
LPSTR pszfLINECALLINFOSTATE[] = { "Unknown LINECALLINFOSTATE state", "LINECALLINFOSTATE_OTHER", "LINECALLINFOSTATE_DEVSPECIFIC", "LINECALLINFOSTATE_BEARERMODE", "LINECALLINFOSTATE_RATE", "LINECALLINFOSTATE_MEDIAMODE", "LINECALLINFOSTATE_APPSPECIFIC", "LINECALLINFOSTATE_CALLID", "LINECALLINFOSTATE_RELATEDCALLID", "LINECALLINFOSTATE_ORIGIN", "LINECALLINFOSTATE_REASON", "LINECALLINFOSTATE_COMPLETIONID", "LINECALLINFOSTATE_NUMOWNERINCR", "LINECALLINFOSTATE_NUMOWNERDECR", "LINECALLINFOSTATE_NUMMONITORS", "LINECALLINFOSTATE_TRUNK", "LINECALLINFOSTATE_CALLERID", "LINECALLINFOSTATE_CALLEDID", "LINECALLINFOSTATE_CONNECTEDID", "LINECALLINFOSTATE_REDIRECTIONID", "LINECALLINFOSTATE_REDIRECTINGID", "LINECALLINFOSTATE_DISPLAY", "LINECALLINFOSTATE_USERUSERINFO", "LINECALLINFOSTATE_HIGHLEVELCOMP", "LINECALLINFOSTATE_LOWLEVELCOMP", "LINECALLINFOSTATE_CHARGINGINFO", "LINECALLINFOSTATE_TERMINAL", "LINECALLINFOSTATE_DIALPARAMS", "LINECALLINFOSTATE_MONITORMODES" };
LPSTR pszfLINECALLSTATE[] = { "Unknown LINECALLSTATE state", "LINECALLSTATE_IDLE", "LINECALLSTATE_OFFERING", "LINECALLSTATE_ACCEPTED", "LINECALLSTATE_DIALTONE", "LINECALLSTATE_DIALING", "LINECALLSTATE_RINGBACK", "LINECALLSTATE_BUSY", "LINECALLSTATE_SPECIALINFO", "LINECALLSTATE_CONNECTED", "LINECALLSTATE_PROCEEDING", "LINECALLSTATE_ONHOLD", "LINECALLSTATE_CONFERENCED", "LINECALLSTATE_ONHOLDPENDCONF", "LINECALLSTATE_ONHOLDPENDTRANSFER", "LINECALLSTATE_DISCONNECTED", "LINECALLSTATE_UNKNOWN" };
LPSTR pszfLINEDIALTONEMODE[] = { "Unknown LINEDIALTONE information", "LINEDIALTONEMODE_NORMAL", "LINEDIALTONEMODE_SPECIAL", "LINEDIALTONEMODE_INTERNAL", "LINEDIALTONEMODE_EXTERNAL", "LINEDIALTONEMODE_UNKNOWN", "LINEDIALTONEMODE_UNAVAIL" };
LPSTR pszfLINEBUSYMODE[] = { "Unknown LINEBUSYMODE information", "LINEBUSYMODE_STATION", "LINEBUSYMODE_TRUNK", "LINEBUSYMODE_UNKNOWN", "LINEBUSYMODE_UNAVAIL" };
LPSTR pszfLINESPECIALINFO[] = { "Unknown LINESPECIALINFO information", "LINESPECIALINFO_NOCIRCUIT", "LINESPECIALINFO_CUSTIRREG", "LINESPECIALINFO_REORDER", "LINESPECIALINFO_UNKNOWN", "LINESPECIALINFO_UNAVAIL" };
LPSTR pszfLINEDISCONNECTED[] = { "Unknown LINEDISCONNECTED information", "LINEDISCONNECTMODE_NORMAL", "LINEDISCONNECTMODE_UNKNOWN", "LINEDISCONNECTMODE_REJECT", "LINEDISCONNECTMODE_PICKUP", "LINEDISCONNECTMODE_FORWARDED", "LINEDISCONNECTMODE_BUSY", "LINEDISCONNECTMODE_NOANSWER", "LINEDISCONNECTMODE_BADADDRESS", "LINEDISCONNECTMODE_UNREACHABLE", "LINEDISCONNECTMODE_CONGESTION", "LINEDISCONNECTMODE_INCOMPATIBLE", "LINEDISCONNECTMODE_UNAVAIL", "LINEDISCONNECTMODE_NODIALTONE" };
LPSTR pszfLINECALLPRIVILEGE[] = { "", "LINECALLPRIVILEGE_NONE", "LINECALLPRIVILEGE_MONITOR", "LINECALLPRIVILEGE_OWNER" };
LPSTR pszfLINEGATHERTERM[] = { "Unknown LINEGATHERTERM message", "LINEGATHERTERM_BUFFERFULL", "LINEGATHERTERM_TERMDIGIT", "LINEGATHERTERM_FIRSTTIMEOUT", "LINEGATHERTERM_INTERTIMEOUT", "LINEGATHERTERM_CANCEL" };
LPSTR pszfLINEGENERATETERM[] = { "Unknown LINEGENERATETERM message", "LINEGENERATETERM_DONE", "LINEGENERATETERM_CANCEL" };
LPSTR pszfLINEDEVSTATE[] = { "Unknown LINEDEVESTATE state", "LINEDEVSTATE_OTHER", "LINEDEVSTATE_RINGING", "LINEDEVSTATE_CONNECTED", "LINEDEVSTATE_DISCONNECTED", "LINEDEVSTATE_MSGWAITON", "LINEDEVSTATE_MSGWAITOFF", "LINEDEVSTATE_INSERVICE", "LINEDEVSTATE_OUTOFSERVICE", "LINEDEVSTATE_MAINTENANCE", "LINEDEVSTATE_OPEN", "LINEDEVSTATE_CLOSE", "LINEDEVSTATE_NUMCALLS", "LINEDEVSTATE_NUMCOMPLETIONS", "LINEDEVSTATE_TERMINALS", "LINEDEVSTATE_ROAMMODE", "LINEDEVSTATE_BATTERY", "LINEDEVSTATE_SIGNAL", "LINEDEVSTATE_DEVSPECIFIC", "LINEDEVSTATE_REINIT", "LINEDEVSTATE_LOCK", "LINEDEVSTATE_CAPSCHANGE", "LINEDEVSTATE_CONFIGCHANGE", "LINEDEVSTATE_TRANSLATECHANGE", "LINEDEVSTATE_COMPLCANCEL", "LINEDEVSTATE_REMOVED" };
LPSTR pszfLINEDIGITMODE[] = { "Unknown LINEDIGITMODE mode", "LINEDIGITMODE_PULSE", "LINEDIGITMODE_DTMF", "LINEDIGITMODE_DTMFEND" };
LPSTR pszfLINEMEDIAMODE[] = { "Unknown LINEMEDIAMODE mode", "UnUsed LINEMEDIAMODE mode, ERROR!!", "LINEMEDIAMODE_UNKNOWN", "LINEMEDIAMODE_INTERACTIVEVOICE", "LINEMEDIAMODE_AUTOMATEDVOICE", "LINEMEDIAMODE_DATAMODEM", "LINEMEDIAMODE_G3FAX", "LINEMEDIAMODE_TDD", "LINEMEDIAMODE_G4FAX", "LINEMEDIAMODE_DIGITALDATA", "LINEMEDIAMODE_TELETEX", "LINEMEDIAMODE_VIDEOTEX", "LINEMEDIAMODE_TELEX", "LINEMEDIAMODE_MIXED", "LINEMEDIAMODE_ADSI", "LINEMEDIAMODE_VOICEVIEW" };
LPSTR pszfLINEREQUESTMODE[] = { "Unknown LINEREQUESTMODE message", "LINEREQUESTMODE_MAKECALL", "LINEREQUESTMODE_MEDIACALL", "LINEREQUESTMODE_DROP" };
//
// MACRO: OutputDebugLineError(long, LPSTR)
//
// PURPOSE: Pretty print a line error to the debugging output.
//
// PARAMETERS:
// lLineError - Actual error code to decipher.
// pszPrefix - String to prepend to the printed message.
//
// RETURN VALUE:
// none
//
// COMMENTS:
// This macro is actually defined in the .h file.
// It will take a LINEERR error, turn it into a human
// readable string, prepend pszPrefix (so you
// can tag your errors), append __FILE__ and __LINE__
// and print it to the debugging output.
// This macro is just a wrapper around OutputDebugLineErrorFileLine
// that is necessary to get proper values for __FILE__ and __LINE__.
//
//
/*
#define OuputDebugLineError(lLineError, pszPrefix) \
OutputDebugLineErrorFileLine(lLineError, pszPrefix,\ __FILE__, __LINE__) */
//
// FUNCTION: OutputDebugLineErrorFileLine(..)
//
// PURPOSE: Pretty print a line error to the debugging output.
//
// PARAMETERS:
// lLineError - Actual error code to decipher.
// pszPrefix - String to prepend to the printed message.
// szFileName - Filename the error occured in.
// nLineNumber - Line number the error occured at.
//
// RETURN VALUE:
// none
//
// COMMENTS:
// This is the actual function that OutputDebugLineError
// expands to. Its not likely to be usefull except
// through the OutputDebugLineError macro, or to print
// errors without line and file information.
//
// If szFileName == NULL, then the File and Line are not printed.
//
// Note that there is an internal string length limit of
// MAXOUTPUTSTRINGLENGTH. If this length is exceeded,
// the behavior will be the same as wsprintf, although
// it will be undetectable. *KEEP szPrefix SHORT!*
//
//
void OutputDebugLineErrorFileLine( long lLineError, LPSTR szPrefix, LPSTR szFileName, DWORD nLineNumber) { LPSTR szLineError; char szOutputLineError[MAXOUTPUTSTRINGLENGTH];
if (szPrefix == NULL) szPrefix = "";
// Pretty print the error message.
szLineError = FormatLineError(lLineError, NULL, 0);
// The only reason FormatLineError should fail is "Out of memory".
if (szLineError == NULL) { if (szFileName == NULL) wsprintf(szOutputLineError, "%sOut of memory", szPrefix); else wsprintf(szOutputLineError, "%sOut of memory in file %s, line %d\r\n", szPrefix, szFileName, nLineNumber);
OutputDebugString(szOutputLineError);
return; }
// If szFileName, then use it; else don't.
if (szFileName != NULL) { wsprintf(szOutputLineError, "%s\r\n\tTapi Line Error: \"%s\" \r\n\tin File \"%s\", Line %d\r\n", szPrefix, szLineError, szFileName, nLineNumber); } else { wsprintf(szOutputLineError, "%s\r\n\tTapi Line Error: \"%s\"\r\n", szPrefix, szLineError); }
// Pointer returned from FormatLineError *must* be freed!
LocalFree(szLineError);
// Print it!
OutputDebugString(szOutputLineError);
return; }
//
// FUNCTION: FormatLineError(long, LPSTR, DWORD)
//
// PURPOSE: Pretty print a line error to a string.
//
// PARAMETERS:
// lLineError - Actual error code to decipher.
// szOutputBuffer - String buffer to pretty print to.
// dwSizeofOutputBuffer - Size of String buffer.
//
// RETURN VALUE:
// Returns the buffer printed to.
//
// COMMENTS:
// If szOutputBuffer isn't big enough to hold the whole string,
// then the string gets truncated to fit the buffer.
//
// If szOutputBuffer == NULL, then dwSizeofOutputBuffer
// is ignored, a buffer 'big enough' is LocalAlloc()d and
// a pointer to it is returned. However, its *very* important
// that this pointer be LocalFree()d by the calling application.
//
//
LPSTR FormatLineError(long lLineError, LPSTR szOutputBuffer, DWORD dwSizeofOutputBuffer) { char szUnknownLineError[256]; LPSTR szLineError; int nSizeofLineError; long lErrorIndex; DWORD * pdwLineError;
// Strip off the high bit to make the error code positive.
pdwLineError = (LPDWORD) &lLineError; lErrorIndex = (long) (0x7FFFFFFF & *pdwLineError);
// Is it an unknown error?
if ((lErrorIndex >= sizeofArray(pszLineErrorNameArray)) || (lErrorIndex < 0)) { nSizeofLineError = wsprintf(szUnknownLineError, "Unknown TAPI line error code: 0x%lx", lLineError); szLineError = szUnknownLineError; } else { szLineError = pszLineErrorNameArray[lErrorIndex]; nSizeofLineError = strlen(szLineError); }
// allocate a buffer if necessary
if (szOutputBuffer == NULL) { szOutputBuffer = (LPSTR) LocalAlloc(LPTR, nSizeofLineError + 1); if (szOutputBuffer == NULL) return NULL; } else // truncate string if it won't fit in the specified buffer.
{ if ((DWORD) nSizeofLineError >= dwSizeofOutputBuffer) nSizeofLineError = dwSizeofOutputBuffer - 1; }
// Put the string into the buffer and null terminate.
memcpy(szOutputBuffer, szLineError, nSizeofLineError); szOutputBuffer[nSizeofLineError] = '\0';
return szOutputBuffer; }
//
// MACRO: OutputDebugLastError(DWORD, LPSTR)
//
// PURPOSE: Pretty print a system error to the debugging output.
//
// PARAMETERS:
// dwLastError - Actual error code to decipher.
// pszPrefix - String to prepend to the printed message.
//
// RETURN VALUE:
// none
//
// COMMENTS:
// This macro is actually defined in the .h file.
// It will take an error that was retrieved by GetLastError(),
// turn it into a human readable string, prepend pszPrefix
// (so you can tag your errors), append __FILE__ and __LINE__
// and print it to the debugging output.
//
// This macro is just a wrapper around OutputDebugLastErrorFileLine
// that is necessary to get proper values for __FILE__ and __LINE__.
//
//
/*
#define OuputDebugLastError(dwLastError, pszPrefix) \
OutputDebugLastErrorFileLine(dwLastError, pszPrefix,\ __FILE__, __LINE__) */
//
// FUNCTION: OutputDebugLastErrorFileLine(..)
//
// PURPOSE: Pretty print a line error to the debugging output.
//
// PARAMETERS:
// dwLastError - Actual error code to decipher.
// pszPrefix - String to prepend to the printed message.
// szFileName - Filename the error occured in.
// nLineNumber - Line number the error occured at.
//
// RETURN VALUE:
// none
//
// COMMENTS:
// This is the actual function that OutputDebugLastError
// expands to. Its not likely to be usefull except
// through the OutputDebugLastError macro or to print
// errors without line and file information.
//
// If szFileName == NULL, then the File and Line are not printed.
//
// Note that there is an internal string length limit of
// MAXOUTPUTSTRINGLENGTH. If this length is exceeded,
// the behavior will be the same as wsprintf, although
// it will be undetectable. *KEEP szPrefix SHORT!*
//
//
void OutputDebugLastErrorFileLine( DWORD dwLastError, LPSTR szPrefix, LPSTR szFileName, DWORD nLineNumber) { LPSTR szLastError; char szOutputLastError[MAXOUTPUTSTRINGLENGTH];
if (szPrefix == NULL) szPrefix = "";
// Pretty print the error.
szLastError = FormatLastError(dwLastError, NULL, 0);
// The only reason FormatLastError should fail is "Out of memory".
if (szLastError == NULL) { if (szFileName == NULL) wsprintf(szOutputLastError, "%sOut of memory\r\n", szPrefix); else wsprintf(szOutputLastError, "%sOut of memory in file %s, line %d\r\n", szPrefix, szFileName, nLineNumber);
OutputDebugString(szOutputLastError);
return; }
// If szFileName, then use it; else don't.
if (szFileName != NULL) { wsprintf(szOutputLastError, "%sGetLastError returned: \"%s\" in File \"%s\", Line %d\r\n", szPrefix, szLastError, szFileName, nLineNumber); } else { wsprintf(szOutputLastError, "%sGetLastError returned: \"%s\"\r\n", szPrefix, szLastError); }
// Pointer returned from FormatLineError *must* be freed!
LocalFree(szLastError);
// Print it!
OutputDebugString(szOutputLastError); return; }
//
// FUNCTION: FormatLastError(DWORD, LPSTR, DWORD)
//
// PURPOSE: Pretty print a system error to a string.
//
// PARAMETERS:
// dwLastError - Actual error code to decipher.
// szOutputBuffer - String buffer to pretty print to.
// dwSizeofOutputBuffer - Size of String buffer.
//
// RETURN VALUE:
// Returns the buffer printed to.
//
// COMMENTS:
// If szOutputBuffer isn't big enough to hold the whole string,
// then the string gets truncated to fit the buffer.
//
// If szOutputBuffer == NULL, then dwSizeofOutputBuffer
// is ignored, a buffer 'big enough' is LocalAlloc()d and
// a pointer to it is returned. However, its *very* important
// that this pointer be LocalFree()d by the calling application.
//
//
LPSTR FormatLastError(DWORD dwLastError, LPSTR szOutputBuffer, DWORD dwSizeofOutputBuffer) { DWORD dwRetFM; DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM;
// Should we allocate a buffer?
if (szOutputBuffer == NULL) { // Actually, we make FormatMessage allocate the buffer, if needed.
dwFlags |= FORMAT_MESSAGE_ALLOCATE_BUFFER;
// minimum size FormatMessage should allocate.
dwSizeofOutputBuffer = 1; }
// Make FormatMessage pretty print the system error.
dwRetFM = FormatMessage( dwFlags, NULL, dwLastError, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (LPTSTR) &szOutputBuffer, dwSizeofOutputBuffer, NULL);
// FormatMessage failed to print the error.
if (dwRetFM == 0) { DWORD dwGetLastError; LPSTR szFormatMessageError;
dwGetLastError = GetLastError();
// If we asked FormatMessage to allocate a buffer, then it
// might have allocated one. Lets be safe and LocalFree it.
if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) { __try { LocalFree(szOutputBuffer); } __except(EXCEPTION_EXECUTE_HANDLER) { // Actually, we do nothing for this fault. If
// there was a fault, it meant the buffer wasn't
// allocated, and the LocalFree was unnecessary.
; }
szOutputBuffer = (char *) LocalAlloc(LPTR, MAXOUTPUTSTRINGLENGTH); dwSizeofOutputBuffer = MAXOUTPUTSTRINGLENGTH;
if (szOutputBuffer == NULL) { OutputDebugString("Out of memory trying to FormatLastError\r\n"); return NULL; } }
szFormatMessageError = FormatLastError(dwGetLastError, NULL, 0);
if (szFormatMessageError == NULL) return NULL;
wsprintf(szOutputBuffer, "FormatMessage failed on error 0x%lx for the following reason: %s", dwLastError, szFormatMessageError);
LocalFree(szFormatMessageError); }
return szOutputBuffer; }
//
// FUNCTION: OutputDebugLineCallback(...)
//
// PURPOSE: Pretty print a message passed into a lineCallbackFunc.
//
// PARAMETERS:
// Standard lineCallbackFunc parameters.
//
// RETURN VALUE:
// none.
//
// COMMENTS:
//
// This function takes all of the parameters passed into a
// lineCallbackFunc callback function, and pretty prints the
// meaning of the message. It then prints the result to
// the debugging output.
//
//
void OutputDebugLineCallback( DWORD dwDevice, DWORD dwMsg, DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) { char szOutputBuff[MAXOUTPUTSTRINGLENGTH];
FormatLineCallback(szOutputBuff, dwDevice, dwMsg, dwCallbackInstance, dwParam1, dwParam2, dwParam3);
strcat(szOutputBuff,"\r\n");
OutputDebugString(szOutputBuff); }
//
// FUNCTION: FormatLineCallback(...)
//
// PURPOSE: Pretty prints into a buffer a lineCallbackFunc message.
//
// PARAMETERS:
// Standard lineCallbackFunc parameters.
//
// RETURN VALUE:
// The pointer to the buffer that has the resulting string.
//
// COMMENTS:
//
// This function takes all of the parameters passed into a
// lineCallbackFunc callback function, and pretty prints the
// meaning of the message. It then returns the pointer to
// the buffer containing this string.
//
// If szOutputBuffer == NULL, then a buffer is LocalAlloc()d
// and returned. However, it is *very* important that this buffer
// is LocalFree()d.
//
LPSTR FormatLineCallback(LPSTR szOutputBuffer, DWORD dwDevice, DWORD dwMsg, DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) { long lBufferIndex = 0;
// Allocate the buffer if necessary.
if (szOutputBuffer == NULL) { szOutputBuffer = (LPSTR) LocalAlloc(LPTR, MAXOUTPUTSTRINGLENGTH);
if (szOutputBuffer == NULL) return NULL; }
// Is this a known message?
if (dwMsg >= sizeofArray(psz_dwMsg)) { wsprintf(szOutputBuffer, "Tapi Msg: Unknown dwMsg: '0x%lx', " "dwDevice: '0x%lx', dwInst: '0x%lx', " "dwP1: '0x%lx', dwP2: '0x%lx', dwP3: '0x%lx'", dwMsg, dwDevice, dwCallbackInstance, dwParam1, dwParam2, dwParam3); return szOutputBuffer; }
// Lets start pretty printing.
lBufferIndex += wsprintf(szOutputBuffer, "Tapi Msg(%s) On(0x%lx)\r\n\t ", psz_dwMsg[dwMsg], dwDevice);
// Which message was it? And start decoding it!
// How the message is decoded depends entirely on the message.
// READ THE HELP FILES if you more information on this.
switch(dwMsg) { case LINE_ADDRESSSTATE: { lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), "Address ID: 0x%lx, Address State: ", dwParam1);
lBufferIndex += strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]), dwParam2, pszfLINEADDRESSSTATE, sizeofArray(pszfLINEADDRESSSTATE));
break; }
case LINE_CALLINFO: { lBufferIndex += strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]), dwParam1, pszfLINECALLINFOSTATE, sizeofArray(pszfLINECALLINFOSTATE));
break; }
case LINE_CALLSTATE: {
lBufferIndex += strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]), dwParam3, pszfLINECALLPRIVILEGE, sizeofArray(pszfLINECALLPRIVILEGE)); lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), "; ");
lBufferIndex += strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]), dwParam1, pszfLINECALLSTATE, sizeofArray(pszfLINECALLSTATE)); switch(dwParam1) { case LINECALLSTATE_DIALTONE: { lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), ": ");
lBufferIndex += strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]), dwParam2, pszfLINEDIALTONEMODE, sizeofArray(pszfLINEDIALTONEMODE));
break; }
case LINECALLSTATE_BUSY: { lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), ": ");
lBufferIndex += strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]), dwParam2, pszfLINEBUSYMODE, sizeofArray(pszfLINEBUSYMODE));
break; }
case LINECALLSTATE_SPECIALINFO: { lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), ": ");
lBufferIndex += strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]), dwParam2, pszfLINESPECIALINFO, sizeofArray(pszfLINESPECIALINFO));
break; }
case LINECALLSTATE_DISCONNECTED: { lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), ": ");
lBufferIndex += strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]), dwParam2, pszfLINEDISCONNECTED, sizeofArray(pszfLINEDISCONNECTED));
break; }
case LINECALLSTATE_CONFERENCED: { lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), ": Parent conference call handle: 0x%lx", dwParam2);
break; } }
break; }
case LINE_CLOSE: break;
case LINE_DEVSPECIFIC: break;
case LINE_DEVSPECIFICFEATURE: break;
case LINE_GATHERDIGITS: { lBufferIndex += strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]), dwParam1, pszfLINEGATHERTERM, sizeofArray(pszfLINEGATHERTERM));
break; }
case LINE_GENERATE: { lBufferIndex += strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]), dwParam1, pszfLINEGENERATETERM, sizeofArray(pszfLINEGENERATETERM));
break; }
case LINE_LINEDEVSTATE: { lBufferIndex += strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]), dwParam1, pszfLINEDEVSTATE, sizeofArray(pszfLINEDEVSTATE));
switch(dwParam1) { case LINEDEVSTATE_RINGING: lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), "; Ring Mode: 0x%lx, Ring Count: %lu" ,dwParam2, dwParam3); break;
case LINEDEVSTATE_REINIT: { switch(dwParam2) { case LINE_CREATE: lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), "; ReInit reason: LINE_CREATE, " "New Line Device ID '0x%lx'" , dwParam3); break; case LINE_LINEDEVSTATE: lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), "; ReInit reason: LINE_LINEDEVSTATE, ");
lBufferIndex += strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]), dwParam3, pszfLINEDEVSTATE, sizeofArray(pszfLINEDEVSTATE));
break; case 0: break; default: lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), "; ReInit reason: %s, dwParam3: 0x%lx" ,psz_dwMsg[dwParam2], dwParam3); break;
}
break; }
default: break; }
break; }
case LINE_MONITORDIGITS: { lBufferIndex += strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]), dwParam2, pszfLINEDIGITMODE, sizeofArray(pszfLINEDIGITMODE));
lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), ", Received: '%c'", LOBYTE(LOWORD(dwParam1))); break; }
case LINE_MONITORMEDIA: { lBufferIndex += strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]), dwParam1, pszfLINEMEDIAMODE, sizeofArray(pszfLINEMEDIAMODE));
break; }
case LINE_MONITORTONE: { lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), "AppSpecific tone '%lu'", dwParam1); break; }
case LINE_REPLY: { if (dwParam2 == 0) { lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), "Request ID: 0x%lx; Successful reply!", dwParam1); } else { char szTmpBuff[256];
FormatLineError((long) dwParam2, szTmpBuff, 255);
lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), "Request ID: 0x%lx; UnSuccessful reply; %s", dwParam1, szTmpBuff); }
break; }
case LINE_REQUEST: { lBufferIndex += strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]), dwParam1, pszfLINEREQUESTMODE, sizeofArray(pszfLINEREQUESTMODE));
switch(dwParam1) { case LINEREQUESTMODE_DROP: { char szHwndName[1024];
SendMessage((HWND) dwParam2, WM_GETTEXT, 1024, (long) szHwndName);
lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), ": hwnd dropping = 0x%lx, \"%s\"; wRequestID = %u", dwParam2, szHwndName, LOWORD(dwParam3)); break; } default: break; }
break; }
case LINE_CREATE: { lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), "New Line Device ID '0x%lx'", dwParam1); break; }
case PHONE_CREATE: { lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), "New Phone Device ID '0x%lx'", dwParam1); break; }
default: lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), "dwParam1: 0x%lx , dwParam2: 0x%lx , dwParam3: 0x%lx", dwParam1, dwParam2, dwParam3); break;
} // End switch(dwMsg)
// return that pointer!
return szOutputBuffer;
}
//
// FUNCTION: strBinaryArrayAppend(LPSTR, DWORD, LPSTR *, DWORD)
//
// PURPOSE: Takes a bitmapped DWORD, an array representing that
// binary mapping, and pretty prints it to a buffer.
//
// PARAMETERS:
// szOutputBuffer - Buffer to print to.
// dwFlags - Binary mapped flags to interpret.
// szStringArray - Array of strings.
// dwSizeofStringArray - number of elements in szStringArray.
//
// RETURN VALUE:
// The number of characters printed into szOutputBuffer.
//
// COMMENTS:
//
// This function takes dwFlags and checks each bit. If the
// bit is set, the appropriate string (taken from szStringArray)
// is printed to the szOutputBuffer string buffer. If there were
// more bits set in the string than elements in the array, and error
// is also tagged on the end.
//
// This function is intended to be used only within the TapiInfo module.
//
static long strBinaryArrayAppend(LPSTR szOutputBuffer, DWORD dwFlags, LPSTR szStringArray[], DWORD dwSizeofStringArray) { DWORD dwIndex = 1, dwPower = 1; long lBufferIndex = 0; BOOL bFirst = TRUE;
// The zeroth element in every bitmapped array is the "unknown" or
// "unchanged" message.
if (dwFlags == 0) { lBufferIndex = wsprintf(szOutputBuffer, "%s", szStringArray[0]); return lBufferIndex; }
// iterate through the flags and check each one.
while(dwIndex < dwSizeofStringArray) { // If we find one, print it.
if (dwFlags & dwPower) // Seporate each printing with a ", " except the first one.
if (bFirst) { lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), "%s", szStringArray[dwIndex]); bFirst = FALSE; } else lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), ", %s", szStringArray[dwIndex]);
dwIndex ++; dwFlags &= ~dwPower; // clear it so we know we checked it.
dwPower *= 2; }
// If there are any flags left, they were not in the array.
if (dwFlags) { if (bFirst) lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), "Unknown flags '0x%lx'", dwFlags); else lBufferIndex += wsprintf(&(szOutputBuffer[lBufferIndex]), ", Unknown flags '0x%lx'", dwFlags); }
// how many did we print into the buffer?
return lBufferIndex; }
//
// FUNCTION: OutputDebugPrintf(LPCSTR, ...)
//
// PURPOSE: wsprintf to the debugging output.
//
// PARAMETERS:
// Exactly the same as wsprintf.
//
// RETURN VALUE:
// none.
//
// COMMENTS:
//
// This function takes exactly the same parameters as wsprintf and
// prints the results to the debugging output.
//
void __cdecl OutputDebugPrintf(LPCSTR lpszFormat, ...) { char szOutput[MAXOUTPUTSTRINGLENGTH]; va_list v1; DWORD dwSize;
va_start(v1, lpszFormat);
dwSize = wvsprintf(szOutput, lpszFormat, v1);
if (szOutput[dwSize-1] != '\n') strcat(szOutput, "\r\n");
OutputDebugString(szOutput); }
|