home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 10 / ioProg_10.iso / soft / platsdk / inetwork.exe / TAPI-S.cab / 44TAPIINFO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-05  |  37.8 KB  |  1,311 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1995-1997  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE: TapiInfo.c
  9. //
  10. //  PURPOSE: Handles all Pretty Printing functions for the TapiComm sample. 
  11. //
  12. //  EXPORTED FUNCTIONS:  These functions are for use by other modules.
  13. //
  14. //      All of these pretty print to the debugging output.
  15. //    OutputDebugLineCallback       - Calls FormatLineCallback.
  16. //    OutputDebugLineError          - Calls OutputDebugLineErrorFileLine.
  17. //    OutputDebugLastError          - Calls OutputDebugLineErrorFileLine.
  18. //    OutputDebugPrintf             - Calls wsprintf
  19. //    OutputDebugLineErrorFileLine  - Calls FormatLineError
  20. //    OutputDebugLastErrorFileLine  - Calls FormatLastError
  21. //
  22. //      All of these functions pretty print to a string buffer.
  23. //    FormatLineError               - Prints a LINEERR
  24. //    FormatLastError               - Prints a GetLastError error.
  25. //    FormatLineCallback            - Prints a lineCallbackFunc message.
  26. //
  27. //  INTERNAL FUNCTION:  These functions are for this module only.
  28. //    strBinaryArrayAppend          - prints a binary flag array to a buffer.
  29.  
  30. #include <windows.h>
  31. #include <tapi.h>
  32. #include "TapiInfo.h"
  33.  
  34. // Maximum length of all internal string buffers.
  35. #define MAXOUTPUTSTRINGLENGTH 4096
  36.  
  37. // define to make accessing arrays easy.
  38. #define sizeofArray(pArray) (sizeof(pArray) / sizeof((pArray)[0]))
  39.  
  40.  
  41. //*****************************************
  42. // Internal prototypes.
  43. //*****************************************
  44.  
  45. static long strBinaryArrayAppend(LPSTR pszOutputBuffer, DWORD dwFlags,
  46.      LPSTR szStringArray[], DWORD dwSizeofStringArray);
  47.  
  48.  
  49.  
  50. //*****************************************
  51. // Global arrays for interpreting TAPI constants.
  52. //*****************************************
  53.  
  54. LPSTR pszLineErrorNameArray[] = 
  55. {
  56. "",
  57. "LINEERR_ALLOCATED",
  58. "LINEERR_BADDEVICEID",
  59. "LINEERR_BEARERMODEUNAVAIL",
  60. "LINEERR Unused constant, ERROR!!",
  61. "LINEERR_CALLUNAVAIL",
  62. "LINEERR_COMPLETIONOVERRUN",
  63. "LINEERR_CONFERENCEFULL",
  64. "LINEERR_DIALBILLING",
  65. "LINEERR_DIALDIALTONE",
  66. "LINEERR_DIALPROMPT",
  67. "LINEERR_DIALQUIET",
  68. "LINEERR_INCOMPATIBLEAPIVERSION",
  69. "LINEERR_INCOMPATIBLEEXTVERSION",
  70. "LINEERR_INIFILECORRUPT",
  71. "LINEERR_INUSE",
  72. "LINEERR_INVALADDRESS",
  73. "LINEERR_INVALADDRESSID",
  74. "LINEERR_INVALADDRESSMODE",
  75. "LINEERR_INVALADDRESSSTATE",
  76. "LINEERR_INVALAPPHANDLE",
  77. "LINEERR_INVALAPPNAME",
  78. "LINEERR_INVALBEARERMODE",
  79. "LINEERR_INVALCALLCOMPLMODE",
  80. "LINEERR_INVALCALLHANDLE",
  81. "LINEERR_INVALCALLPARAMS",
  82. "LINEERR_INVALCALLPRIVILEGE",
  83. "LINEERR_INVALCALLSELECT",
  84. "LINEERR_INVALCALLSTATE",
  85. "LINEERR_INVALCALLSTATELIST",
  86. "LINEERR_INVALCARD",
  87. "LINEERR_INVALCOMPLETIONID",
  88. "LINEERR_INVALCONFCALLHANDLE",
  89. "LINEERR_INVALCONSULTCALLHANDLE",
  90. "LINEERR_INVALCOUNTRYCODE",
  91. "LINEERR_INVALDEVICECLASS",
  92. "LINEERR_INVALDEVICEHANDLE",
  93. "LINEERR_INVALDIALPARAMS",
  94. "LINEERR_INVALDIGITLIST",
  95. "LINEERR_INVALDIGITMODE",
  96. "LINEERR_INVALDIGITS",
  97. "LINEERR_INVALEXTVERSION",
  98. "LINEERR_INVALGROUPID",
  99. "LINEERR_INVALLINEHANDLE",
  100. "LINEERR_INVALLINESTATE",
  101. "LINEERR_INVALLOCATION",
  102. "LINEERR_INVALMEDIALIST",
  103. "LINEERR_INVALMEDIAMODE",
  104. "LINEERR_INVALMESSAGEID",
  105. "LINEERR Unused constant, ERROR!!",
  106. "LINEERR_INVALPARAM",
  107. "LINEERR_INVALPARKID",
  108. "LINEERR_INVALPARKMODE",
  109. "LINEERR_INVALPOINTER",
  110. "LINEERR_INVALPRIVSELECT",
  111. "LINEERR_INVALRATE",
  112. "LINEERR_INVALREQUESTMODE",
  113. "LINEERR_INVALTERMINALID",
  114. "LINEERR_INVALTERMINALMODE",
  115. "LINEERR_INVALTIMEOUT",
  116. "LINEERR_INVALTONE",
  117. "LINEERR_INVALTONELIST",
  118. "LINEERR_INVALTONEMODE",
  119. "LINEERR_INVALTRANSFERMODE",
  120. "LINEERR_LINEMAPPERFAILED",
  121. "LINEERR_NOCONFERENCE",
  122. "LINEERR_NODEVICE",
  123. "LINEERR_NODRIVER",
  124. "LINEERR_NOMEM",
  125. "LINEERR_NOREQUEST",
  126. "LINEERR_NOTOWNER",
  127. "LINEERR_NOTREGISTERED",
  128. "LINEERR_OPERATIONFAILED",
  129. "LINEERR_OPERATIONUNAVAIL",
  130. "LINEERR_RATEUNAVAIL",
  131. "LINEERR_RESOURCEUNAVAIL",
  132. "LINEERR_REQUESTOVERRUN",
  133. "LINEERR_STRUCTURETOOSMALL",
  134. "LINEERR_TARGETNOTFOUND",
  135. "LINEERR_TARGETSELF",
  136. "LINEERR_UNINITIALIZED",
  137. "LINEERR_USERUSERINFOTOOBIG",
  138. "LINEERR_REINIT",
  139. "LINEERR_ADDRESSBLOCKED",
  140. "LINEERR_BILLINGREJECTED",
  141. "LINEERR_INVALFEATURE",
  142. "LINEERR_NOMULTIPLEINSTANCE"
  143. };
  144.  
  145.  
  146. LPSTR psz_dwMsg[] = {
  147.     "LINE_ADDRESSSTATE",
  148.     "LINE_CALLINFO",
  149.     "LINE_CALLSTATE",
  150.     "LINE_CLOSE",
  151.     "LINE_DEVSPECIFIC",
  152.     "LINE_DEVSPECIFICFEATURE",
  153.     "LINE_GATHERDIGITS",
  154.     "LINE_GENERATE",
  155.     "LINE_LINEDEVSTATE",
  156.     "LINE_MONITORDIGITS",
  157.     "LINE_MONITORMEDIA",
  158.     "LINE_MONITORTONE",
  159.     "LINE_REPLY",
  160.     "LINE_REQUEST",
  161.     "PHONE_BUTTON",
  162.     "PHONE_CLOSE",
  163.     "PHONE_DEVSPECIFIC",
  164.     "PHONE_REPLY",
  165.     "PHONE_STATE",
  166.     "LINE_CREATE",
  167.     "PHONE_CREATE"
  168. };
  169.  
  170.  
  171. LPSTR pszfLINEADDRESSSTATE[] = 
  172. {
  173.     "Unknown LINEADDRESSSTATE information",
  174.     "LINEADDRESSSTATE_OTHER",
  175.     "LINEADDRESSSTATE_DEVSPECIFIC",
  176.     "LINEADDRESSSTATE_INUSEZERO",
  177.     "LINEADDRESSSTATE_INUSEONE",
  178.     "LINEADDRESSSTATE_INUSEMANY",
  179.     "LINEADDRESSSTATE_NUMCALLS",
  180.     "LINEADDRESSSTATE_FORWARD",
  181.     "LINEADDRESSSTATE_TERMINALS",
  182.     "LINEADDRESSSTATE_CAPSCHANGE"
  183. };
  184.  
  185.  
  186. LPSTR pszfLINECALLINFOSTATE[] = 
  187. {
  188.     "Unknown LINECALLINFOSTATE state",
  189.     "LINECALLINFOSTATE_OTHER",
  190.     "LINECALLINFOSTATE_DEVSPECIFIC",
  191.     "LINECALLINFOSTATE_BEARERMODE",
  192.     "LINECALLINFOSTATE_RATE",
  193.     "LINECALLINFOSTATE_MEDIAMODE",
  194.     "LINECALLINFOSTATE_APPSPECIFIC",
  195.     "LINECALLINFOSTATE_CALLID",
  196.     "LINECALLINFOSTATE_RELATEDCALLID",
  197.     "LINECALLINFOSTATE_ORIGIN",
  198.     "LINECALLINFOSTATE_REASON",
  199.     "LINECALLINFOSTATE_COMPLETIONID",
  200.     "LINECALLINFOSTATE_NUMOWNERINCR",
  201.     "LINECALLINFOSTATE_NUMOWNERDECR",
  202.     "LINECALLINFOSTATE_NUMMONITORS",
  203.     "LINECALLINFOSTATE_TRUNK",
  204.     "LINECALLINFOSTATE_CALLERID",
  205.     "LINECALLINFOSTATE_CALLEDID",
  206.     "LINECALLINFOSTATE_CONNECTEDID",
  207.     "LINECALLINFOSTATE_REDIRECTIONID",
  208.     "LINECALLINFOSTATE_REDIRECTINGID",
  209.     "LINECALLINFOSTATE_DISPLAY",
  210.     "LINECALLINFOSTATE_USERUSERINFO",
  211.     "LINECALLINFOSTATE_HIGHLEVELCOMP",
  212.     "LINECALLINFOSTATE_LOWLEVELCOMP",
  213.     "LINECALLINFOSTATE_CHARGINGINFO",
  214.     "LINECALLINFOSTATE_TERMINAL",
  215.     "LINECALLINFOSTATE_DIALPARAMS",
  216.     "LINECALLINFOSTATE_MONITORMODES"
  217. };
  218.  
  219.  
  220. LPSTR pszfLINECALLSTATE[] = 
  221. {
  222.     "Unknown LINECALLSTATE state",
  223.     "LINECALLSTATE_IDLE",
  224.     "LINECALLSTATE_OFFERING",
  225.     "LINECALLSTATE_ACCEPTED",
  226.     "LINECALLSTATE_DIALTONE",
  227.     "LINECALLSTATE_DIALING",
  228.     "LINECALLSTATE_RINGBACK",
  229.     "LINECALLSTATE_BUSY",
  230.     "LINECALLSTATE_SPECIALINFO",
  231.     "LINECALLSTATE_CONNECTED",
  232.     "LINECALLSTATE_PROCEEDING",
  233.     "LINECALLSTATE_ONHOLD",
  234.     "LINECALLSTATE_CONFERENCED",
  235.     "LINECALLSTATE_ONHOLDPENDCONF",
  236.     "LINECALLSTATE_ONHOLDPENDTRANSFER",
  237.     "LINECALLSTATE_DISCONNECTED",
  238.     "LINECALLSTATE_UNKNOWN"
  239. };
  240.  
  241.  
  242. LPSTR pszfLINEDIALTONEMODE[] =
  243. {
  244.     "Unknown LINEDIALTONE information",
  245.     "LINEDIALTONEMODE_NORMAL",
  246.     "LINEDIALTONEMODE_SPECIAL",
  247.     "LINEDIALTONEMODE_INTERNAL",
  248.     "LINEDIALTONEMODE_EXTERNAL",
  249.     "LINEDIALTONEMODE_UNKNOWN",
  250.     "LINEDIALTONEMODE_UNAVAIL"
  251. };
  252.  
  253.  
  254. LPSTR pszfLINEBUSYMODE[] =
  255. {
  256.     "Unknown LINEBUSYMODE information",
  257.     "LINEBUSYMODE_STATION",
  258.     "LINEBUSYMODE_TRUNK",
  259.     "LINEBUSYMODE_UNKNOWN",
  260.     "LINEBUSYMODE_UNAVAIL"
  261. };
  262.  
  263.  
  264. LPSTR pszfLINESPECIALINFO[] =
  265. {
  266.     "Unknown LINESPECIALINFO information",
  267.     "LINESPECIALINFO_NOCIRCUIT",
  268.     "LINESPECIALINFO_CUSTIRREG",
  269.     "LINESPECIALINFO_REORDER",
  270.     "LINESPECIALINFO_UNKNOWN",
  271.     "LINESPECIALINFO_UNAVAIL"
  272. };
  273.  
  274.  
  275. LPSTR pszfLINEDISCONNECTED[] =
  276. {
  277.     "Unknown LINEDISCONNECTED information",
  278.     "LINEDISCONNECTMODE_NORMAL",
  279.     "LINEDISCONNECTMODE_UNKNOWN",
  280.     "LINEDISCONNECTMODE_REJECT",
  281.     "LINEDISCONNECTMODE_PICKUP",
  282.     "LINEDISCONNECTMODE_FORWARDED",
  283.     "LINEDISCONNECTMODE_BUSY",
  284.     "LINEDISCONNECTMODE_NOANSWER",
  285.     "LINEDISCONNECTMODE_BADADDRESS",
  286.     "LINEDISCONNECTMODE_UNREACHABLE",
  287.     "LINEDISCONNECTMODE_CONGESTION",
  288.     "LINEDISCONNECTMODE_INCOMPATIBLE",
  289.     "LINEDISCONNECTMODE_UNAVAIL",
  290.     "LINEDISCONNECTMODE_NODIALTONE"
  291. };
  292.  
  293.  
  294. LPSTR pszfLINECALLPRIVILEGE[] =
  295. {
  296.     "No change to LINECALLPRIVILEGE",
  297.     "LINECALLPRIVILEGE_NONE",
  298.     "LINECALLPRIVILEGE_MONITOR",
  299.     "LINECALLPRIVILEGE_OWNER"
  300. };
  301.  
  302.  
  303. LPSTR pszfLINEGATHERTERM[] =
  304. {
  305.     "Unknown LINEGATHERTERM message",
  306.     "LINEGATHERTERM_BUFFERFULL",
  307.     "LINEGATHERTERM_TERMDIGIT",
  308.     "LINEGATHERTERM_FIRSTTIMEOUT",
  309.     "LINEGATHERTERM_INTERTIMEOUT",
  310.     "LINEGATHERTERM_CANCEL"
  311. };
  312.  
  313.  
  314. LPSTR pszfLINEGENERATETERM[] = 
  315. {
  316.     "Unknown LINEGENERATETERM message",
  317.     "LINEGENERATETERM_DONE",
  318.     "LINEGENERATETERM_CANCEL"
  319. };
  320.  
  321.  
  322. LPSTR pszfLINEDEVSTATE[] =
  323. {    
  324.     "Unknown LINEDEVESTATE state",
  325.     "LINEDEVSTATE_OTHER",
  326.     "LINEDEVSTATE_RINGING",
  327.     "LINEDEVSTATE_CONNECTED",
  328.     "LINEDEVSTATE_DISCONNECTED",
  329.     "LINEDEVSTATE_MSGWAITON",
  330.     "LINEDEVSTATE_MSGWAITOFF",
  331.     "LINEDEVSTATE_INSERVICE",
  332.     "LINEDEVSTATE_OUTOFSERVICE",
  333.     "LINEDEVSTATE_MAINTENANCE",
  334.     "LINEDEVSTATE_OPEN",
  335.     "LINEDEVSTATE_CLOSE",
  336.     "LINEDEVSTATE_NUMCALLS",
  337.     "LINEDEVSTATE_NUMCOMPLETIONS",
  338.     "LINEDEVSTATE_TERMINALS",
  339.     "LINEDEVSTATE_ROAMMODE",
  340.     "LINEDEVSTATE_BATTERY",
  341.     "LINEDEVSTATE_SIGNAL",
  342.     "LINEDEVSTATE_DEVSPECIFIC",
  343.     "LINEDEVSTATE_REINIT",
  344.     "LINEDEVSTATE_LOCK",
  345.     "LINEDEVSTATE_CAPSCHANGE",
  346.     "LINEDEVSTATE_CONFIGCHANGE",
  347.     "LINEDEVSTATE_TRANSLATECHANGE",
  348.     "LINEDEVSTATE_COMPLCANCEL",
  349.     "LINEDEVSTATE_REMOVED"
  350. };
  351.  
  352.  
  353. LPSTR pszfLINEDIGITMODE[] =
  354. {
  355.     "Unknown LINEDIGITMODE mode",
  356.     "LINEDIGITMODE_PULSE",
  357.     "LINEDIGITMODE_DTMF",
  358.     "LINEDIGITMODE_DTMFEND"
  359. };
  360.     
  361.  
  362. LPSTR pszfLINEMEDIAMODE[] =
  363. {
  364.     "Unknown LINEMEDIAMODE mode",
  365.     "UnUsed LINEMEDIAMODE mode, ERROR!!",
  366.     "LINEMEDIAMODE_UNKNOWN",
  367.     "LINEMEDIAMODE_INTERACTIVEVOICE",
  368.     "LINEMEDIAMODE_AUTOMATEDVOICE",
  369.     "LINEMEDIAMODE_DATAMODEM",
  370.     "LINEMEDIAMODE_G3FAX",
  371.     "LINEMEDIAMODE_TDD",
  372.     "LINEMEDIAMODE_G4FAX",
  373.     "LINEMEDIAMODE_DIGITALDATA",
  374.     "LINEMEDIAMODE_TELETEX",
  375.     "LINEMEDIAMODE_VIDEOTEX",
  376.     "LINEMEDIAMODE_TELEX",
  377.     "LINEMEDIAMODE_MIXED",
  378.     "LINEMEDIAMODE_ADSI",
  379.     "LINEMEDIAMODE_VOICEVIEW"
  380. };
  381.  
  382.  
  383. LPSTR pszfLINEREQUESTMODE[] =
  384. {
  385.     "Unknown LINEREQUESTMODE message",
  386.     "LINEREQUESTMODE_MAKECALL",
  387.     "LINEREQUESTMODE_MEDIACALL",
  388.     "LINEREQUESTMODE_DROP"
  389. };
  390.  
  391.  
  392. //
  393. //  MACRO: OutputDebugLineError(long, LPSTR)
  394. //
  395. //  PURPOSE: Pretty print a line error to the debugging output.
  396. //
  397. //  PARAMETERS:
  398. //    lLineError - Actual error code to decipher.
  399. //    pszPrefix  - String to prepend to the printed message.
  400. //
  401. //  RETURN VALUE:
  402. //    none
  403. //
  404. //  COMMENTS:
  405. //    This macro is actually defined in the .h file.
  406. //    It will take a LINEERR error, turn it into a human
  407. //    readable string, prepend pszPrefix (so you
  408. //    can tag your errors), append __FILE__ and __LINE__
  409. //    and print it to the debugging output.
  410.  
  411. //    This macro is just a wrapper around OutputDebugLineErrorFileLine
  412. //    that is necessary to get proper values for __FILE__ and __LINE__.
  413. //
  414. //
  415.  
  416.  
  417. /*
  418. #define OuputDebugLineError(lLineError, pszPrefix) \
  419.     OutputDebugLineErrorFileLine(lLineError, pszPrefix,\
  420.         __FILE__, __LINE__)
  421. */
  422.  
  423. //
  424. //  FUNCTION: OutputDebugLineErrorFileLine(..)
  425. //
  426. //  PURPOSE: Pretty print a line error to the debugging output.
  427. //
  428. //  PARAMETERS:
  429. //    lLineError  - Actual error code to decipher.
  430. //    pszPrefix   - String to prepend to the printed message.
  431. //    szFileName  - Filename the error occured in.
  432. //    nLineNumber - Line number the error occured at.
  433. //
  434. //  RETURN VALUE:
  435. //    none
  436. //
  437. //  COMMENTS:
  438. //    This is the actual function that OutputDebugLineError
  439. //    expands to.  Its not likely to be usefull except
  440. //    through the OutputDebugLineError macro, or to print
  441. //    errors without line and file information.
  442. //
  443. //    If szFileName == NULL, then the File and Line are not printed.
  444. //   
  445. //    Note that there is an internal string length limit of
  446. //    MAXOUTPUTSTRINGLENGTH.  If this length is exceeded,
  447. //    the behavior will be the same as wsprintf, although
  448. //    it will be undetectable.  *KEEP szPrefix SHORT!*
  449. //
  450. //
  451.  
  452. void OutputDebugLineErrorFileLine(
  453.     long lLineError, LPSTR szPrefix, 
  454.     LPSTR szFileName, DWORD nLineNumber)
  455. {
  456.     LPSTR szLineError;
  457.     char szOutputLineError[MAXOUTPUTSTRINGLENGTH];
  458.  
  459.     if (szPrefix == NULL)
  460.         szPrefix = "";
  461.  
  462.     // Pretty print the error message.
  463.     szLineError = FormatLineError(lLineError, NULL, 0);
  464.  
  465.     // The only reason FormatLineError should fail is "Out of memory".
  466.     if (szLineError == NULL)
  467.     {
  468.         if (szFileName == NULL)
  469.             wsprintf(szOutputLineError, "%sOut of memory", szPrefix);
  470.         else
  471.             wsprintf(szOutputLineError, 
  472.                 "%sOut of memory in file %s, line %d\r\n",
  473.                 szPrefix, szFileName, nLineNumber);
  474.  
  475.         OutputDebugString(szOutputLineError);
  476.  
  477.         return;
  478.     }
  479.  
  480.     // If szFileName, then use it; else don't.
  481.     if (szFileName != NULL)
  482.     {
  483.         wsprintf(szOutputLineError,
  484.             "%sTapi Line Error: \"%s\" in File \"%s\", Line %d\r\n",
  485.             szPrefix, szLineError, szFileName, nLineNumber);
  486.     }
  487.     else
  488.     {
  489.         wsprintf(szOutputLineError,
  490.             "%sTapi Line Error: \"%s\"\r\n",
  491.             szPrefix, szLineError);
  492.     }
  493.  
  494.     // Pointer returned from FormatLineError *must* be freed!
  495.     LocalFree(szLineError);
  496.  
  497.     // Print it!
  498.     OutputDebugString(szOutputLineError);
  499.  
  500.     return;
  501. }
  502.  
  503.  
  504. //
  505. //  FUNCTION: FormatLineError(long, LPSTR, DWORD)
  506. //
  507. //  PURPOSE: Pretty print a line error to a string.
  508. //
  509. //  PARAMETERS:
  510. //    lLineError           - Actual error code to decipher.
  511. //    szOutputBuffer       - String buffer to pretty print to.
  512. //    dwSizeofOutputBuffer - Size of String buffer.
  513. //
  514. //  RETURN VALUE:
  515. //    Returns the buffer printed to.
  516. //
  517. //  COMMENTS:
  518. //    If szOutputBuffer isn't big enough to hold the whole string,
  519. //    then the string gets truncated to fit the buffer.
  520. //
  521. //    If szOutputBuffer == NULL, then dwSizeofOutputBuffer
  522. //    is ignored, a buffer 'big enough' is LocalAlloc()d and
  523. //    a pointer to it is returned.  However, its *very* important
  524. //    that this pointer be LocalFree()d by the calling application.
  525. //
  526. //
  527.  
  528. LPSTR FormatLineError(long lLineError,
  529.     LPSTR szOutputBuffer, DWORD dwSizeofOutputBuffer)
  530. {
  531.     char szUnknownLineError[256];
  532.     LPSTR szLineError;
  533.     int nSizeofLineError;
  534.     long lErrorIndex;
  535.     DWORD * pdwLineError;
  536.  
  537.     // Strip off the high bit to make the error code positive.
  538.     pdwLineError = &lLineError;
  539.     lErrorIndex = (long) (0x7FFFFFFF & *pdwLineError);
  540.  
  541.     // Is it an unknown error?
  542.     if ((lErrorIndex >= sizeofArray(pszLineErrorNameArray)) ||
  543.         (lErrorIndex < 0))
  544.     {
  545.         nSizeofLineError = 
  546.             wsprintf(szUnknownLineError, "Unknown TAPI line error code: 0x%lx",
  547.                 lLineError);
  548.         szLineError = szUnknownLineError;
  549.     }
  550.     else
  551.     {
  552.         szLineError = pszLineErrorNameArray[lErrorIndex];
  553.         nSizeofLineError = strlen(szLineError);
  554.     }
  555.  
  556.     // allocate a buffer if necessary
  557.     if (szOutputBuffer == NULL)
  558.     {
  559.         szOutputBuffer = (LPSTR) LocalAlloc(LPTR, nSizeofLineError + 1);
  560.         if (szOutputBuffer == NULL)
  561.             return NULL;
  562.     }
  563.     else // truncate string if it won't fit in the specified buffer.
  564.     {
  565.         if ((DWORD) nSizeofLineError >= dwSizeofOutputBuffer)
  566.             nSizeofLineError = dwSizeofOutputBuffer - 1;
  567.     }
  568.  
  569.     // Put the string into the buffer and null terminate.
  570.     memcpy(szOutputBuffer, szLineError, nSizeofLineError);
  571.     szOutputBuffer[nSizeofLineError] = '\0';
  572.  
  573.     return szOutputBuffer;
  574. }
  575.  
  576.  
  577. //
  578. //  MACRO: OutputDebugLastError(DWORD, LPSTR)
  579. //
  580. //  PURPOSE: Pretty print a system error to the debugging output.
  581. //
  582. //  PARAMETERS:
  583. //    dwLastError - Actual error code to decipher.
  584. //    pszPrefix   - String to prepend to the printed message.
  585. //
  586. //  RETURN VALUE:
  587. //    none
  588. //
  589. //  COMMENTS:
  590. //    This macro is actually defined in the .h file.
  591. //    It will take an error that was retrieved by GetLastError(),
  592. //    turn it into a human readable string, prepend pszPrefix
  593. //    (so you can tag your errors), append __FILE__ and __LINE__
  594. //    and print it to the debugging output.
  595. //
  596. //    This macro is just a wrapper around OutputDebugLastErrorFileLine
  597. //    that is necessary to get proper values for __FILE__ and __LINE__.
  598. //
  599. //
  600.  
  601. /*
  602. #define OuputDebugLastError(dwLastError, pszPrefix) \
  603.     OutputDebugLastErrorFileLine(dwLastError, pszPrefix,\
  604.         __FILE__, __LINE__)
  605. */
  606.  
  607.  
  608. //
  609. //  FUNCTION: OutputDebugLastErrorFileLine(..)
  610. //
  611. //  PURPOSE: Pretty print a line error to the debugging output.
  612. //
  613. //  PARAMETERS:
  614. //    dwLastError - Actual error code to decipher.
  615. //    pszPrefix   - String to prepend to the printed message.
  616. //    szFileName  - Filename the error occured in.
  617. //    nLineNumber - Line number the error occured at.
  618. //
  619. //  RETURN VALUE:
  620. //    none
  621. //
  622. //  COMMENTS:
  623. //    This is the actual function that OutputDebugLastError
  624. //    expands to.  Its not likely to be usefull except
  625. //    through the OutputDebugLastError macro or to print
  626. //    errors without line and file information.
  627. //
  628. //    If szFileName == NULL, then the File and Line are not printed.
  629. //   
  630. //    Note that there is an internal string length limit of
  631. //    MAXOUTPUTSTRINGLENGTH.  If this length is exceeded,
  632. //    the behavior will be the same as wsprintf, although
  633. //    it will be undetectable.  *KEEP szPrefix SHORT!*
  634. //
  635. //
  636.  
  637. void OutputDebugLastErrorFileLine(
  638.     DWORD dwLastError, LPSTR szPrefix, 
  639.     LPSTR szFileName, DWORD nLineNumber)
  640. {
  641.     LPSTR szLastError;
  642.     char szOutputLastError[MAXOUTPUTSTRINGLENGTH];
  643.  
  644.     if (szPrefix == NULL)
  645.         szPrefix = "";
  646.  
  647.     // Pretty print the error.
  648.     szLastError = FormatLastError(dwLastError, NULL, 0);
  649.  
  650.     // The only reason FormatLastError should fail is "Out of memory".
  651.     if (szLastError == NULL)
  652.     {
  653.         if (szFileName == NULL)
  654.             wsprintf(szOutputLastError, "%sOut of memory\r\n", szPrefix);
  655.         else
  656.             wsprintf(szOutputLastError, "%sOut of memory in file %s, line %d\r\n",
  657.                 szPrefix, szFileName, nLineNumber);
  658.  
  659.         OutputDebugString(szOutputLastError);
  660.  
  661.         return;
  662.     }
  663.  
  664.     // If szFileName, then use it; else don't.
  665.     if (szFileName != NULL)
  666.     {
  667.         wsprintf(szOutputLastError,
  668.             "%sGetLastError returned: \"%s\" in File \"%s\", Line %d\r\n",
  669.             szPrefix, szLastError, szFileName, nLineNumber);
  670.     }
  671.     else
  672.     {
  673.         wsprintf(szOutputLastError,
  674.             "%sGetLastError returned: \"%s\"\r\n",
  675.             szPrefix, szLastError);
  676.     }
  677.  
  678.     // Pointer returned from FormatLineError *must* be freed!
  679.     LocalFree(szLastError);
  680.  
  681.     // Print it!
  682.     OutputDebugString(szOutputLastError);
  683.     return;
  684. }
  685.  
  686.  
  687. //
  688. //  FUNCTION: FormatLastError(DWORD, LPSTR, DWORD)
  689. //
  690. //  PURPOSE: Pretty print a system error to a string.
  691. //
  692. //  PARAMETERS:
  693. //    dwLastError          - Actual error code to decipher.
  694. //    szOutputBuffer       - String buffer to pretty print to.
  695. //    dwSizeofOutputBuffer - Size of String buffer.
  696. //
  697. //  RETURN VALUE:
  698. //    Returns the buffer printed to.
  699. //
  700. //  COMMENTS:
  701. //    If szOutputBuffer isn't big enough to hold the whole string,
  702. //    then the string gets truncated to fit the buffer.
  703. //
  704. //    If szOutputBuffer == NULL, then dwSizeofOutputBuffer
  705. //    is ignored, a buffer 'big enough' is LocalAlloc()d and
  706. //    a pointer to it is returned.  However, its *very* important
  707. //    that this pointer be LocalFree()d by the calling application.
  708. //
  709. //
  710.  
  711. LPSTR FormatLastError(DWORD dwLastError,
  712.     LPSTR szOutputBuffer, DWORD dwSizeofOutputBuffer)
  713. {
  714.     DWORD dwRetFM;
  715.     DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM;
  716.  
  717.     // Should we allocate a buffer?
  718.     if (szOutputBuffer == NULL)
  719.     {
  720.         // Actually, we make FormatMessage allocate the buffer, if needed.
  721.         dwFlags |= FORMAT_MESSAGE_ALLOCATE_BUFFER;
  722.  
  723.         // minimum size FormatMessage should allocate.
  724.         dwSizeofOutputBuffer = 1;  
  725.     }
  726.  
  727.     // Make FormatMessage pretty print the system error.
  728.     dwRetFM = FormatMessage(
  729.         dwFlags, NULL, dwLastError,
  730.         MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
  731.         (LPTSTR) &szOutputBuffer, dwSizeofOutputBuffer,
  732.         NULL);
  733.  
  734.     // FormatMessage failed to print the error.
  735.     if (dwRetFM == 0)
  736.     {
  737.         DWORD dwGetLastError;
  738.         LPSTR szFormatMessageError;
  739.  
  740.         dwGetLastError = GetLastError();
  741.  
  742.         // If we asked FormatMessage to allocate a buffer, then it
  743.         // might have allocated one.  Lets be safe and LocalFree it.
  744.         if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER)
  745.         {
  746.             __try
  747.             {
  748.                 LocalFree(szOutputBuffer);
  749.             }
  750.             __except(EXCEPTION_EXECUTE_HANDLER)
  751.             {
  752.                 // Actually, we do nothing for this fault.  If
  753.                 // there was a fault, it meant the buffer wasn't
  754.                 // allocated, and the LocalFree was unnecessary.
  755.                 ;
  756.             }
  757.  
  758.             szOutputBuffer = LocalAlloc(LPTR, MAXOUTPUTSTRINGLENGTH);
  759.             dwSizeofOutputBuffer = MAXOUTPUTSTRINGLENGTH;
  760.  
  761.             if (szOutputBuffer == NULL)
  762.             {
  763.                 OutputDebugString("Out of memory trying to FormatLastError\r\n");
  764.                 return NULL;
  765.             }
  766.         }
  767.  
  768.         szFormatMessageError = 
  769.             FormatLastError(dwGetLastError, NULL, 0);
  770.  
  771.         if (szFormatMessageError == NULL)
  772.             return NULL;
  773.  
  774.         wsprintf(szOutputBuffer, 
  775.             "FormatMessage failed on error 0x%lx for the following reason: %s",
  776.             dwLastError, szFormatMessageError);
  777.  
  778.         LocalFree(szFormatMessageError);
  779.     }
  780.  
  781.     return szOutputBuffer;
  782. }
  783.  
  784.  
  785. //
  786. //  FUNCTION: OutputDebugLineCallback(...)
  787. //
  788. //  PURPOSE: Pretty print a message passed into a lineCallbackFunc.
  789. //
  790. //  PARAMETERS:
  791. //    Standard lineCallbackFunc parameters.
  792. //
  793. //  RETURN VALUE:
  794. //    none.
  795. //
  796. //  COMMENTS:
  797. //
  798. //    This function takes all of the parameters passed into a
  799. //    lineCallbackFunc callback function, and pretty prints the
  800. //    meaning of the message.  It then prints the result to
  801. //    the debugging output.
  802. //
  803. //
  804.  
  805. void OutputDebugLineCallback(
  806.     DWORD dwDevice, DWORD dwMsg, DWORD dwCallbackInstance, 
  807.     DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
  808. {
  809.     char szOutputBuff[MAXOUTPUTSTRINGLENGTH];
  810.  
  811.     FormatLineCallback(szOutputBuff, 
  812.         dwDevice, dwMsg, dwCallbackInstance, 
  813.         dwParam1, dwParam2, dwParam3);
  814.  
  815.     strcat(szOutputBuff,"\r\n");
  816.  
  817.     OutputDebugString(szOutputBuff);
  818. }
  819.  
  820.  
  821. //
  822. //  FUNCTION: FormatLineCallback(...)
  823. //
  824. //  PURPOSE: Pretty prints into a buffer a lineCallbackFunc message.
  825. //
  826. //  PARAMETERS:
  827. //    Standard lineCallbackFunc parameters.
  828. //
  829. //  RETURN VALUE:
  830. //    The pointer to the buffer that has the resulting string.
  831. //
  832. //  COMMENTS:
  833. //
  834. //    This function takes all of the parameters passed into a
  835. //    lineCallbackFunc callback function, and pretty prints the
  836. //    meaning of the message.  It then returns the pointer to
  837. //    the buffer containing this string.
  838. //
  839. //    If szOutputBuffer == NULL, then a buffer is LocalAlloc()d
  840. //    and returned.  However, it is *very* important that this buffer
  841. //    is LocalFree()d.
  842. //
  843.  
  844. LPSTR FormatLineCallback(LPSTR szOutputBuffer,
  845.     DWORD dwDevice, DWORD dwMsg, DWORD dwCallbackInstance, 
  846.     DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
  847. {
  848.     long lBufferIndex = 0;
  849.  
  850.     // Allocate the buffer if necessary.
  851.     if (szOutputBuffer == NULL)
  852.     {
  853.         szOutputBuffer = (LPSTR) LocalAlloc(LPTR, MAXOUTPUTSTRINGLENGTH);
  854.  
  855.         if (szOutputBuffer == NULL)
  856.             return NULL;
  857.     }
  858.  
  859.     // Is this a known message?
  860.     if (dwMsg >= sizeofArray(psz_dwMsg))
  861.     {
  862.         wsprintf(szOutputBuffer, "lineCallback: Unknown dwMsg: '0x%lx', "
  863.             "dwDevice: '0x%lx', dwCallbackInstance: '0x%lx', "
  864.             "dwParam1: '0x%lx', dwParam2: '0x%lx', dwParam3: '0x%lx'", dwMsg, 
  865.             dwDevice, dwCallbackInstance, dwParam1, dwParam2, dwParam3);
  866.         return szOutputBuffer;
  867.     }
  868.  
  869.     // Lets start pretty printing.
  870.     lBufferIndex +=
  871.         wsprintf(szOutputBuffer, "lineCallback: %s; dwDevice: '0x%lx'; ",
  872.             psz_dwMsg[dwMsg], dwDevice);
  873.  
  874.     // Which message was it?  And start decoding it!
  875.     // How the message is decoded depends entirely on the message.
  876.     // READ THE HELP FILES if you more information on this.
  877.     switch(dwMsg)
  878.     {
  879.         case LINE_ADDRESSSTATE:
  880.         {
  881.             lBufferIndex +=
  882.                 wsprintf(&(szOutputBuffer[lBufferIndex]),
  883.                     "Address ID: 0x%lx, Address State: ", dwParam1);
  884.  
  885.             lBufferIndex +=
  886.                 strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]),
  887.                     dwParam2,
  888.                     pszfLINEADDRESSSTATE, sizeofArray(pszfLINEADDRESSSTATE));
  889.  
  890.             break;
  891.         }
  892.  
  893.         case LINE_CALLINFO:
  894.         {
  895.             lBufferIndex +=
  896.                 strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]),
  897.                     dwParam1,
  898.                     pszfLINECALLINFOSTATE, sizeofArray(pszfLINECALLINFOSTATE));
  899.  
  900.             break;
  901.         }
  902.  
  903.         case LINE_CALLSTATE:
  904.         {
  905.  
  906.             lBufferIndex +=
  907.                 strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]),
  908.                     dwParam3,
  909.                     pszfLINECALLPRIVILEGE, sizeofArray(pszfLINECALLPRIVILEGE));
  910.             lBufferIndex +=
  911.                 wsprintf(&(szOutputBuffer[lBufferIndex]),
  912.                     "; ");
  913.  
  914.             lBufferIndex += 
  915.                 strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]),
  916.                     dwParam1,
  917.                     pszfLINECALLSTATE, sizeofArray(pszfLINECALLSTATE));
  918.     
  919.             switch(dwParam1)
  920.             {
  921.                 case LINECALLSTATE_DIALTONE:
  922.                 {
  923.                     lBufferIndex +=
  924.                         wsprintf(&(szOutputBuffer[lBufferIndex]),
  925.                             ": ");
  926.  
  927.                     lBufferIndex += 
  928.                         strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]),
  929.                         dwParam2,
  930.                         pszfLINEDIALTONEMODE, sizeofArray(pszfLINEDIALTONEMODE));
  931.  
  932.                     break;
  933.                 }
  934.  
  935.                 case LINECALLSTATE_BUSY:
  936.                 {
  937.                     lBufferIndex +=
  938.                         wsprintf(&(szOutputBuffer[lBufferIndex]),
  939.                             ": ");
  940.  
  941.                     lBufferIndex += 
  942.                         strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]),
  943.                         dwParam2,
  944.                         pszfLINEBUSYMODE, sizeofArray(pszfLINEBUSYMODE));
  945.  
  946.                     break;
  947.                 }
  948.  
  949.                 case LINECALLSTATE_SPECIALINFO:
  950.                 {
  951.                     lBufferIndex +=
  952.                         wsprintf(&(szOutputBuffer[lBufferIndex]),
  953.                             ": ");
  954.  
  955.                     lBufferIndex += 
  956.                         strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]),
  957.                         dwParam2,
  958.                         pszfLINESPECIALINFO, sizeofArray(pszfLINESPECIALINFO));
  959.  
  960.                     break;
  961.                 }
  962.  
  963.                 case LINECALLSTATE_DISCONNECTED:
  964.                 {
  965.                     lBufferIndex +=
  966.                         wsprintf(&(szOutputBuffer[lBufferIndex]),
  967.                             ": ");
  968.  
  969.                     lBufferIndex += 
  970.                         strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]),
  971.                         dwParam2,
  972.                         pszfLINEDISCONNECTED, sizeofArray(pszfLINEDISCONNECTED));
  973.  
  974.                     break;
  975.                 }
  976.  
  977.                 case LINECALLSTATE_CONFERENCED:
  978.                 {
  979.                     lBufferIndex +=
  980.                         wsprintf(&(szOutputBuffer[lBufferIndex]),
  981.                             ": Parent conference call handle: 0x%lx", dwParam2);
  982.  
  983.                     break;
  984.                 }
  985.             }
  986.  
  987.             break;
  988.         }
  989.  
  990.         case LINE_CLOSE:
  991.             break;
  992.  
  993.         case LINE_DEVSPECIFIC:
  994.             break;
  995.  
  996.         case LINE_DEVSPECIFICFEATURE:
  997.             break;
  998.  
  999.         case LINE_GATHERDIGITS:
  1000.         {
  1001.             lBufferIndex +=
  1002.                 strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]),
  1003.                     dwParam1,
  1004.                     pszfLINEGATHERTERM, sizeofArray(pszfLINEGATHERTERM));
  1005.  
  1006.             break;
  1007.         }
  1008.  
  1009.         case LINE_GENERATE:
  1010.         {
  1011.             lBufferIndex +=
  1012.                 strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]),
  1013.                     dwParam1,
  1014.                     pszfLINEGENERATETERM, sizeofArray(pszfLINEGENERATETERM));
  1015.  
  1016.             break;
  1017.         }
  1018.  
  1019.         case LINE_LINEDEVSTATE:
  1020.         {
  1021.             lBufferIndex +=
  1022.                 strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]),
  1023.                     dwParam1,
  1024.                     pszfLINEDEVSTATE, sizeofArray(pszfLINEDEVSTATE));
  1025.  
  1026.             switch(dwParam1)
  1027.             {
  1028.                 case LINEDEVSTATE_RINGING:
  1029.                     lBufferIndex +=
  1030.                         wsprintf(&(szOutputBuffer[lBufferIndex]),
  1031.                             "; Ring Mode: 0x%lx, Ring Count: %lu"
  1032.                             ,dwParam2, dwParam3);
  1033.                     break;
  1034.  
  1035.                 case LINEDEVSTATE_REINIT:
  1036.                 {
  1037.                     switch(dwParam2)
  1038.                     {
  1039.                         case LINE_CREATE:
  1040.                             lBufferIndex +=
  1041.                                 wsprintf(&(szOutputBuffer[lBufferIndex]),
  1042.                                     "; ReInit reason: LINE_CREATE, "
  1043.                                         "New Line Device ID '0x%lx'"
  1044.                                     , dwParam3);
  1045.                             break;
  1046.                             
  1047.                         case LINE_LINEDEVSTATE:
  1048.                             lBufferIndex +=
  1049.                                 wsprintf(&(szOutputBuffer[lBufferIndex]),
  1050.                                     "; ReInit reason: LINE_LINEDEVSTATE, ");
  1051.  
  1052.                             lBufferIndex +=
  1053.                                 strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]),
  1054.                                     dwParam3,
  1055.                                     pszfLINEDEVSTATE, sizeofArray(pszfLINEDEVSTATE));
  1056.  
  1057.                             break;
  1058.                         
  1059.                         case 0:
  1060.                             break;
  1061.                         default:
  1062.                             lBufferIndex +=
  1063.                                 wsprintf(&(szOutputBuffer[lBufferIndex]),
  1064.                                     "; ReInit reason: %s, dwParam3: 0x%lx"
  1065.                                     ,psz_dwMsg[dwParam2], dwParam3);
  1066.                             break;
  1067.  
  1068.                     }
  1069.  
  1070.                     break;
  1071.                 }
  1072.  
  1073.                 default:
  1074.                     break;
  1075.             }
  1076.  
  1077.             break;
  1078.         }
  1079.  
  1080.         case LINE_MONITORDIGITS:
  1081.         {
  1082.             lBufferIndex += 
  1083.                 strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]),
  1084.                 dwParam2,
  1085.                 pszfLINEDIGITMODE, sizeofArray(pszfLINEDIGITMODE));
  1086.  
  1087.             lBufferIndex +=
  1088.                 wsprintf(&(szOutputBuffer[lBufferIndex]),
  1089.                     ", Received: '%c'", LOBYTE(LOWORD(dwParam1)));
  1090.             
  1091.             break;
  1092.         }
  1093.  
  1094.         case LINE_MONITORMEDIA:
  1095.         {
  1096.             lBufferIndex +=
  1097.                 strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]),
  1098.                     dwParam1,
  1099.                     pszfLINEMEDIAMODE, sizeofArray(pszfLINEMEDIAMODE));
  1100.  
  1101.             break;
  1102.         }
  1103.  
  1104.         case LINE_MONITORTONE:
  1105.         {
  1106.             lBufferIndex +=
  1107.                 wsprintf(&(szOutputBuffer[lBufferIndex]),
  1108.                     "AppSpecific tone '%lu'", dwParam1);
  1109.             break;
  1110.         }
  1111.  
  1112.         case LINE_REPLY:
  1113.         {
  1114.             if (dwParam2 == 0)
  1115.             {
  1116.                 lBufferIndex +=
  1117.                     wsprintf(&(szOutputBuffer[lBufferIndex]),
  1118.                         "Request ID: 0x%lx; Successful reply!", dwParam1);
  1119.             }
  1120.             else
  1121.             {
  1122.                 char szTmpBuff[256];
  1123.  
  1124.                 FormatLineError((long) dwParam2, szTmpBuff, 255);
  1125.  
  1126.                 lBufferIndex +=
  1127.                     wsprintf(&(szOutputBuffer[lBufferIndex]),
  1128.                         "Request ID: 0x%lx; UnSuccessful reply; %s",
  1129.                         dwParam1, szTmpBuff);
  1130.             }
  1131.  
  1132.             break;
  1133.         }
  1134.  
  1135.         case LINE_REQUEST:
  1136.         {
  1137.             lBufferIndex += 
  1138.                 strBinaryArrayAppend(&(szOutputBuffer[lBufferIndex]),
  1139.                 dwParam1,
  1140.                 pszfLINEREQUESTMODE, sizeofArray(pszfLINEREQUESTMODE));
  1141.  
  1142.             switch(dwParam1)
  1143.             {
  1144.                 case LINEREQUESTMODE_DROP:
  1145.                 {
  1146.                     char szHwndName[1024];
  1147.  
  1148.                     SendMessage((HWND) dwParam2, WM_GETTEXT, 1024, (long) szHwndName);
  1149.  
  1150.                     lBufferIndex +=
  1151.                         wsprintf(&(szOutputBuffer[lBufferIndex]),
  1152.                             ": hwnd dropping = 0x%lx, \"%s\"; wRequestID = %u",
  1153.                             dwParam2, szHwndName, LOWORD(dwParam3));
  1154.                     break;
  1155.                 }
  1156.                 default:
  1157.                     break;
  1158.             }
  1159.  
  1160.             break;
  1161.         }
  1162.  
  1163.         case LINE_CREATE:
  1164.         {
  1165.             lBufferIndex +=
  1166.                 wsprintf(&(szOutputBuffer[lBufferIndex]),
  1167.                     "New Line Device ID '0x%lx'", dwParam1);
  1168.             break;
  1169.         }
  1170.  
  1171.         case PHONE_CREATE:
  1172.         {
  1173.             lBufferIndex +=
  1174.                 wsprintf(&(szOutputBuffer[lBufferIndex]),
  1175.                     "New Phone Device ID '0x%lx'", dwParam1);
  1176.             break;
  1177.         }
  1178.  
  1179.         default:
  1180.             lBufferIndex +=
  1181.                 wsprintf(&(szOutputBuffer[lBufferIndex]),
  1182.                     "dwParam1: 0x%lx , dwParam2: 0x%lx , dwParam3: 0x%lx",
  1183.                     dwParam1, dwParam2, dwParam3);
  1184.             break;
  1185.  
  1186.     } // End switch(dwMsg)
  1187.  
  1188.     // return that pointer!
  1189.     return szOutputBuffer;
  1190.  
  1191. }
  1192.  
  1193.  
  1194. //
  1195. //  FUNCTION: strBinaryArrayAppend(LPSTR, DWORD, LPSTR *, DWORD)
  1196. //
  1197. //  PURPOSE: Takes a bitmapped DWORD, an array representing that
  1198. //    binary mapping, and pretty prints it to a buffer.
  1199. //
  1200. //  PARAMETERS:
  1201. //    szOutputBuffer      - Buffer to print to.
  1202. //    dwFlags             - Binary mapped flags to interpret.
  1203. //    szStringArray       - Array of strings.
  1204. //    dwSizeofStringArray - number of elements in szStringArray.
  1205.  
  1206. //
  1207. //  RETURN VALUE:
  1208. //    The number of characters printed into szOutputBuffer.
  1209. //
  1210. //  COMMENTS:
  1211. //
  1212. //    This function takes dwFlags and checks each bit.  If the
  1213. //    bit is set, the appropriate string (taken from szStringArray)
  1214. //    is printed to the szOutputBuffer string buffer.  If there were
  1215. //    more bits set in the string than elements in the array, and error
  1216. //    is also tagged on the end.
  1217. //
  1218. //    This function is intended to be used only within the TapiInfo module.
  1219. //
  1220.  
  1221. static long strBinaryArrayAppend(LPSTR szOutputBuffer, DWORD dwFlags,
  1222.      LPSTR szStringArray[], DWORD dwSizeofStringArray)
  1223. {
  1224.     DWORD dwIndex = 1, dwPower = 1;
  1225.     long lBufferIndex = 0;
  1226.     BOOL bFirst = TRUE;
  1227.  
  1228.     // The zeroth element in every bitmapped array is the "unknown" or
  1229.     // "unchanged" message.
  1230.     if (dwFlags == 0)
  1231.     {
  1232.         lBufferIndex =
  1233.             wsprintf(szOutputBuffer, "%s", szStringArray[0]);
  1234.         return lBufferIndex;
  1235.     }
  1236.  
  1237.     // iterate through the flags and check each one.
  1238.     while(dwIndex < dwSizeofStringArray)
  1239.     {
  1240.         // If we find one, print it.
  1241.         if (dwFlags & dwPower)
  1242.             // Seporate each printing with a ", " except the first one.
  1243.             if (bFirst)
  1244.             {
  1245.                 lBufferIndex +=
  1246.                     wsprintf(&(szOutputBuffer[lBufferIndex]),
  1247.                         "%s", szStringArray[dwIndex]);
  1248.                 bFirst = FALSE;
  1249.             }
  1250.             else
  1251.                 lBufferIndex +=
  1252.                     wsprintf(&(szOutputBuffer[lBufferIndex]),
  1253.                         ", %s", szStringArray[dwIndex]);
  1254.  
  1255.         dwIndex ++;
  1256.         dwFlags &= ~dwPower;  // clear it so we know we checked it.
  1257.         dwPower *= 2;
  1258.     }
  1259.  
  1260.     // If there are any flags left, they were not in the array.
  1261.     if (dwFlags)
  1262.     {
  1263.         if (bFirst)
  1264.             lBufferIndex +=
  1265.                 wsprintf(&(szOutputBuffer[lBufferIndex]),
  1266.                     "Unknown flags '0x%lx'", dwFlags);
  1267.         else
  1268.             lBufferIndex +=
  1269.                 wsprintf(&(szOutputBuffer[lBufferIndex]),
  1270.                     ", Unknown flags '0x%lx'", dwFlags);
  1271.     }
  1272.  
  1273.     // how many did we print into the buffer?
  1274.     return lBufferIndex;
  1275. }
  1276.  
  1277.  
  1278.  
  1279. //
  1280. //  FUNCTION: OutputDebugPrintf(LPCSTR, ...)
  1281. //
  1282. //  PURPOSE: wsprintf to the debugging output.
  1283. //
  1284. //  PARAMETERS:
  1285. //    Exactly the same as wsprintf.
  1286. //
  1287. //  RETURN VALUE:
  1288. //    none.
  1289. //
  1290. //  COMMENTS:
  1291. //
  1292. //    This function takes exactly the same parameters as wsprintf and
  1293. //    prints the results to the debugging output.
  1294. //
  1295.  
  1296. void __cdecl OutputDebugPrintf(LPCSTR lpszFormat, ...)
  1297. {
  1298.     char szOutput[MAXOUTPUTSTRINGLENGTH];
  1299.     va_list v1;
  1300.     DWORD dwSize;
  1301.  
  1302.     va_start(v1, lpszFormat);
  1303.  
  1304.     dwSize = wvsprintf(szOutput, lpszFormat, v1);
  1305.  
  1306.     if (szOutput[dwSize-1] != '\n')
  1307.         strcat(szOutput, "\r\n");
  1308.  
  1309.     OutputDebugString(szOutput);
  1310. }
  1311.