home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rxasyn20.zip / MISCFUNC.C < prev    next >
Text File  |  1994-12-26  |  21KB  |  548 lines

  1. //*****************************************************************************/
  2. /*                                                                           */
  3. /*  MODULE         MISCFUNC.C                                                */
  4. /*                                                                           */
  5. /*  VERSION        Version 2.0 - 26th Dec 1994                               */
  6. /*                                                                           */
  7. /*  COPYRIGHT      Copyright (c) 1993, 1994 by Crucial Applications          */
  8. /*                             All rights reserved.                          */
  9. /*                                                                           */
  10. /*  DESCRIPTION    Miscellaneous Support Functions                           */
  11. /*                                                                           */
  12. /*  FUNCTIONS                                                                */
  13. /*                                                                           */
  14. /*    Str2Num      - Convert specified string to a number                    */
  15. /*    Val2Str      - Convert specified value to a string                     */
  16. /*    MyDiffTime   - Return difference between two times                     */
  17. /*    SetPriority  - Set current thread priority                             */
  18. /*    MsgBox       - Generic PM message box function                         */
  19. /*    MsgBoxThread - Thread function for MsgBox routine                      */
  20. /*                                                                           */
  21. /*****************************************************************************/
  22.  
  23. /*********************************************************************/
  24. /* Includes                                                          */
  25. /*********************************************************************/
  26.  
  27. #define  _MT
  28. #define  _DLL
  29. #define  INCL_DOS
  30. #define  INCL_ERRORS
  31.  
  32. #include <os2.h>
  33. #include <time.h>
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <stdlib.h>
  37.  
  38. #include "miscfunc.h"
  39.  
  40. /*********************************************************************/
  41. /* Function:  Str2Num( numstr, numptr, numtype )                     */
  42. /*                                                                   */
  43. /* Purpose:   Validates and converts an ASCII-Z string from string   */
  44. /*            form to designated value.  Returns FALSE if the string */
  45. /*            is not valid, TRUE if the string was successfully      */
  46. /*            converted.                                             */
  47. /*                                                                   */
  48. /*            Source types             Target types                  */
  49. /*            ----------------------   ----------------------        */
  50. /*            BINARY    '01001100'     BYTE                          */
  51. /*            OCTAL     '765'          SHORT                         */
  52. /*            DECIMAL   '12345'        USHORT                        */
  53. /*            HEX       '0A'           LONG                          */
  54. /*                                     ULONG                         */
  55. /*                                     PSZ                           */
  56. /*                                                                   */
  57. /* Return:    TRUE - Good string converted                           */
  58. /*            FALSE - Invalid string supplied.                       */
  59. /*********************************************************************/
  60. BOOL Str2Num( PSZ NumStr, PVOID pNumber, USHORT NumType )
  61. {
  62.    ULONG  Tnumber;
  63.    ULONG  Tmax;
  64.    USHORT Trad;
  65.    USHORT Tlen;
  66.    USHORT Tind;
  67.    USHORT Tpos;
  68.    SHORT  Tsgn;
  69.    CHAR   Tdig[2];
  70.  
  71.    Tnumber = 0;
  72.    Tmax    = 0;
  73.    Trad    = 0;
  74.    Tlen    = 0;
  75.    Tind    = 0;
  76.    Tpos    = 0;
  77.    Tsgn    = 0;
  78.    Tdig[0] = EOSTR_CH;
  79.    Tdig[1] = EOSTR_CH;
  80.  
  81.    switch( NumType )
  82.    {
  83.       case STR2NUM_STR2STR:    /* string  to string */ Tlen =  0; Trad =  0; Tmax = 0;              break;
  84.       case STR2NUM_BIN2BYTE:   /* binary  to byte   */ Tlen =  8; Trad =  2; Tmax = MAX_BYTE_DEC;   break;
  85.       case STR2NUM_BIN2SHORT:  /* binary  to short  */ Tlen = 16; Trad =  2; Tmax = MAX_SHORT_DEC;  break;
  86.       case STR2NUM_BIN2USHORT: /* binary  to ushort */ Tlen = 16; Trad =  2; Tmax = MAX_USHORT_DEC; break;
  87.       case STR2NUM_BIN2LONG:   /* binary  to long   */ Tlen = 32; Trad =  2; Tmax = MAX_LONG_DEC;   break;
  88.       case STR2NUM_BIN2ULONG:  /* binary  to ulong  */ Tlen = 32; Trad =  2; Tmax = MAX_ULONG_DEC;  break;
  89.       case STR2NUM_OCT2BYTE:   /* octal   to byte   */ Tlen =  3; Trad =  8; Tmax = MAX_BYTE_DEC;   break;
  90.       case STR2NUM_OCT2SHORT:  /* octal   to short  */ Tlen =  6; Trad =  8; Tmax = MAX_SHORT_DEC;  break;
  91.       case STR2NUM_OCT2USHORT: /* octal   to ushort */ Tlen =  6; Trad =  8; Tmax = MAX_USHORT_DEC; break;
  92.       case STR2NUM_OCT2LONG:   /* octal   to long   */ Tlen =  9; Trad =  8; Tmax = MAX_LONG_DEC;   break;
  93.       case STR2NUM_OCT2ULONG:  /* octal   to ulong  */ Tlen =  9; Trad =  8; Tmax = MAX_ULONG_DEC;  break;
  94.       case STR2NUM_DEC2BYTE:   /* decimal to byte   */ Tlen =  3; Trad = 10; Tmax = MAX_BYTE_DEC;   break;
  95.       case STR2NUM_DEC2SHORT:  /* decimal to short  */ Tlen =  5; Trad = 10; Tmax = MAX_SHORT_DEC;  break;
  96.       case STR2NUM_DEC2USHORT: /* decimal to ushort */ Tlen =  5; Trad = 10; Tmax = MAX_USHORT_DEC; break;
  97.       case STR2NUM_DEC2LONG:   /* decimal to long   */ Tlen = 10; Trad = 10; Tmax = MAX_LONG_DEC;   break;
  98.       case STR2NUM_DEC2ULONG:  /* decimal to ulong  */ Tlen = 10; Trad = 10; Tmax = MAX_ULONG_DEC;  break;
  99.       case STR2NUM_HEX2BYTE:   /* hex     to byte   */ Tlen =  2; Trad = 16; Tmax = MAX_BYTE_DEC;   break;
  100.       case STR2NUM_HEX2SHORT:  /* hex     to short  */ Tlen =  4; Trad = 16; Tmax = MAX_SHORT_DEC;  break;
  101.       case STR2NUM_HEX2USHORT: /* hex     to ushort */ Tlen =  4; Trad = 16; Tmax = MAX_USHORT_DEC; break;
  102.       case STR2NUM_HEX2LONG:   /* hex     to long   */ Tlen =  8; Trad = 16; Tmax = MAX_LONG_DEC;   break;
  103.       case STR2NUM_HEX2ULONG:  /* hex     to ulong  */ Tlen =  8; Trad = 16; Tmax = MAX_ULONG_DEC;  break;
  104.       default:
  105.            return( FALSE );
  106.    }
  107.  
  108.    if ( Tlen > 0 ) {
  109.  
  110.       while (isspace( *NumStr )) { NumStr++; } /* skip leading blanks */
  111.  
  112.       if (*NumStr == '+') { NumStr++; } /* skip positive sign */
  113.  
  114.       if (*NumStr == '-') {
  115.          switch( NumType )
  116.          {
  117.             case STR2NUM_DEC2SHORT:
  118.             case STR2NUM_DEC2LONG:
  119.                  /* to short or long */
  120.                  break;
  121.             default:
  122.                  return( FALSE );
  123.          }
  124.          Tsgn = -1;
  125.          NumStr++;
  126.       } /* set negative and skip sign */
  127.  
  128.       if (strlen( NumStr ) == 0) { return( FALSE ); } /* not a number */
  129.  
  130.       Tind = 0;
  131.       Tpos = 0;
  132.  
  133.       do {
  134.          Tdig[0] = NumStr[0];
  135.          Tind = strcspn( DIGIT_CHARS, Tdig );
  136.  
  137.          if ((Trad == 16) && (Tind > 15)) { Tind = Tind - 6; } /* lowercase hex adjust */
  138.  
  139.          if (Tind < Trad)
  140.          {
  141.             Tnumber = Tnumber*Trad + Tind;
  142.  
  143.             if (Tnumber > (Tmax - Tsgn)) { return( FALSE ); } /* exceeds bounds */
  144.  
  145.             Tpos = Tpos + 1;
  146.             NumStr++;
  147.  
  148.          } /* else not a valid digit or end of string */
  149.  
  150.       } while ((Tpos < Tlen) && (Tind < Trad));
  151.  
  152.       while (isspace( *NumStr )) { NumStr++; }     /* skip trailing blanks */
  153.  
  154.       if (*NumStr != EOSTR_CH) { return( FALSE ); } /* not a number */
  155.    }
  156.  
  157.    switch( NumType )
  158.    {
  159.       case STR2NUM_STR2STR:
  160.            /* to string */
  161.            strcpy( pNumber, NumStr );
  162.            break;
  163.       case STR2NUM_BIN2BYTE:
  164.       case STR2NUM_OCT2BYTE:
  165.       case STR2NUM_DEC2BYTE:
  166.       case STR2NUM_HEX2BYTE:
  167.            /* to byte   */
  168.            *((PBYTE) pNumber)   = (BYTE) Tnumber;
  169.            break;
  170.       case STR2NUM_BIN2SHORT:
  171.       case STR2NUM_OCT2SHORT:
  172.       case STR2NUM_DEC2SHORT:
  173.       case STR2NUM_HEX2SHORT:
  174.            /* to short  */
  175.            if (Tsgn < 0) {
  176.               *((PSHORT) pNumber)  = (SHORT) 0 - (SHORT) Tnumber;
  177.            } else {
  178.               *((PSHORT) pNumber)  = (SHORT) Tnumber;
  179.            }
  180.            break;
  181.       case STR2NUM_BIN2USHORT:
  182.       case STR2NUM_OCT2USHORT:
  183.       case STR2NUM_DEC2USHORT:
  184.       case STR2NUM_HEX2USHORT:
  185.            /* to ushort */
  186.            *((PUSHORT) pNumber) = (USHORT) Tnumber;
  187.            break;
  188.       case STR2NUM_BIN2LONG:
  189.       case STR2NUM_OCT2LONG:
  190.       case STR2NUM_DEC2LONG:
  191.       case STR2NUM_HEX2LONG:
  192.            /* to long   */
  193.            if (Tsgn < 0) {
  194.               *((PLONG) pNumber)   = (LONG) 0 - (LONG) Tnumber;
  195.            } else {
  196.               *((PLONG) pNumber)   = (LONG) Tnumber;
  197.            }
  198.            break;
  199.       case STR2NUM_BIN2ULONG:
  200.       case STR2NUM_OCT2ULONG:
  201.       case STR2NUM_DEC2ULONG:
  202.       case STR2NUM_HEX2ULONG:
  203.            /* to ulong  */
  204.            *((PULONG) pNumber)  = (ULONG) Tnumber;
  205.            break;
  206.       default:
  207.            return( FALSE );
  208.    }
  209.  
  210.    return( TRUE );
  211. }
  212.  
  213. /*********************************************************************/
  214. /* Function:  Val2Str( valptr, valstr, valtype )                     */
  215. /*                                                                   */
  216. /* Purpose:   Converts value of specified type to an ASCII-Z string. */
  217. /*                                                                   */
  218. /* Return:    none                                                   */
  219. /*********************************************************************/
  220. VOID Val2Str( PVOID pValue, PSZ ValStr, USHORT ValType )
  221. {
  222.    ValStr[0] = EOSTR_CH;
  223.  
  224.    switch( ValType )
  225.    {
  226.       case VAL2STR_STR2STR:    strcpy(  ValStr,          (PSZ)pValue        ); break;
  227.       case VAL2STR_HFILE2DEC:  sprintf( ValStr,    "%d", *((PHFILE)pValue)  ); break;
  228.  
  229.       case VAL2STR_BYTE2DEC:   sprintf( ValStr,    "%d", *((PBYTE)pValue)   ); break;
  230.       case VAL2STR_SHORT2DEC:  sprintf( ValStr,    "%d", *((PSHORT)pValue)  ); break;
  231.       case VAL2STR_USHORT2DEC: sprintf( ValStr,    "%d", *((PUSHORT)pValue) ); break;
  232.       case VAL2STR_LONG2DEC:   sprintf( ValStr,    "%d", *((PLONG)pValue)   ); break;
  233.       case VAL2STR_ULONG2DEC:  sprintf( ValStr,    "%d", *((PULONG)pValue)  ); break;
  234.  
  235.       case VAL2STR_BYTE2HEX:   sprintf( ValStr, "%2.2X", *((PBYTE)pValue)   ); break;
  236.       case VAL2STR_SHORT2HEX:  sprintf( ValStr, "%4.4X", *((PSHORT)pValue)  ); break;
  237.       case VAL2STR_USHORT2HEX: sprintf( ValStr, "%4.4X", *((PUSHORT)pValue) ); break;
  238.       case VAL2STR_LONG2HEX:   sprintf( ValStr, "%8.8X", *((PLONG)pValue)   ); break;
  239.       case VAL2STR_ULONG2HEX:  sprintf( ValStr, "%8.8X", *((PULONG)pValue)  ); break;
  240.  
  241.       default:
  242.            strcpy( ValStr, (PSZ)pValue );
  243.            break;
  244.    }
  245.  
  246.    return;
  247. }
  248.  
  249. /*********************************************************************/
  250. /* Function:  MyDiffTime( &now, &then )                              */
  251. /*                                                                   */
  252. /* Purpose:   Calculates the difference in hundredths of a second    */
  253. /*            between two specified times. The maximum difference    */
  254. /*            permitted is 23hrs 59min 99/100ths.                    */
  255. /*                                                                   */
  256. /* Return:    difference in milliseconds.                            */
  257. /*********************************************************************/
  258. LONG MyDiffTime(
  259.         PDATETIME Tnow,
  260.         PDATETIME Tthen )
  261. {
  262.    LONG  Tdiff;
  263.    SHORT Tdays, Thours, Tmins, Tsecs, Thunds;
  264.  
  265.    Tdays   = Tnow->weekday    - Tthen->weekday;
  266.    Thours  = Tnow->hours      - Tthen->hours;
  267.    Tmins   = Tnow->minutes    - Tthen->minutes;
  268.    Tsecs   = Tnow->seconds    - Tthen->seconds;
  269.    Thunds  = Tnow->hundredths - Tthen->hundredths;
  270.  
  271.    if (Thunds  < 0) { Thunds  = Thunds  + 100; Tsecs   = Tsecs   - 1; }
  272.    if (Tsecs   < 0) { Tsecs   = Tsecs   + 60;  Tmins   = Tmins   - 1; }
  273.    if (Tmins   < 0) { Tmins   = Tmins   + 60;  Thours  = Thours  - 1; }
  274.    if (Thours  < 0) { Thours  = Thours  + 24;  Tdays   = Tdays   - 1; }
  275.    if (Tdays   < 0) { Tdays   = Tdays   + 7; }
  276.  
  277.    if (Tdays != 0)
  278.       Tdiff = -1;    /* do not handle, too long a period */
  279.    else
  280.       Tdiff = Thunds
  281.             + (100*Tsecs)
  282.             + (100*60*Tmins)
  283.             + (100*60*60*Thours);
  284.  
  285.    return( Tdiff*10 );                 /* return as milliseconds     */
  286. }
  287.  
  288. /*********************************************************************/
  289. /* SetPriority()                                                     */
  290. /*********************************************************************/
  291. APIRET SetPriority( ULONG ulClass, LONG lLevel )
  292. {
  293.    APIRET    rc;                        /* creation return code       */
  294.  
  295.    rc = DosSetPrty( PRTYS_THREAD,
  296.                     ulClass,
  297.                     lLevel,
  298.                     0 );               /* current process/thread     */
  299.  
  300.    if ( rc != NO_ERROR ) {
  301.       fprintf( stdout, "DosSetPrty(%d,%d) failed with RC=%d.\r\n", ulClass, lLevel, rc );
  302.    }
  303.  
  304.    return( rc );                       /* Return DosSetPriority rc   */
  305.  
  306. } /* end SetPriority() */
  307.  
  308. /*********************************************************************/
  309. /* MsgBox()                                                          */
  310. /*********************************************************************/
  311. APIRET MsgBox(
  312.           PSZ    pszTitle,
  313.           CHAR   chIcon,
  314.           CHAR   chButtons,
  315.           CHAR   chHelp,
  316.           USHORT usNumber,
  317.           PSZ    pszText )
  318. {
  319.    USHORT  usReply;
  320.    MYMSG   msgMyMsg;
  321.    PMYMSG  pMsg;
  322.  
  323.    pMsg = &msgMyMsg;
  324.  
  325.    /* Set message struct with parameters */
  326.  
  327.    pMsg->tidMyMsg   = NULLHANDLE;
  328.    pMsg->habMyMsg   = NULLHANDLE;
  329.    pMsg->hmqMyMsg   = NULLHANDLE;
  330.    pMsg->hwndMyMsg  = NULLHANDLE;
  331.  
  332.    if ( pszTitle == NULL ) {
  333.       strcpy( pMsg->szTitle, MSG_DEFAULT_TITLE );
  334.    } else {
  335.       strncpy( pMsg->szTitle, pszTitle, MSG_TITLE_LEN );
  336.       (pMsg->szTitle)[MSG_TITLE_LEN] = EOSTR_CH;
  337.    }
  338.  
  339.    pMsg->chIcon    = chIcon;
  340.    pMsg->chButtons = chButtons;
  341.    pMsg->chHelp    = chHelp;
  342.    pMsg->usNumber  = usNumber;
  343.  
  344.    if ( pszText == NULL ) {
  345.       strcpy( pMsg->szText, EMPTY_STR );
  346.    } else {
  347.       strcpy( pMsg->szText, pszText );
  348.    }
  349.  
  350.    pMsg->usReply = MSG_RESPONSE_IGNORE;
  351.  
  352.    // if msgno not zero then build msg string from msgno
  353.    // using msgtext for parameters (linefeed delimited),
  354.    // any excess parameters are to be ignored, any
  355.    // missing parameters need to be replaced with '<?>'
  356.  
  357.    pMsg->usNumber = 0;                  /* no help just yet */
  358.  
  359.    pMsg->tidMyMsg = _beginthread( MsgBoxThread, NULL, MSG_STACK_SIZE, (PVOID) pMsg );
  360.  
  361.    if ( pMsg->tidMyMsg == -1 ) {
  362.       DosBeep(750,500);
  363.    } else {
  364.       DosWaitThread( &(pMsg->tidMyMsg), DCWW_WAIT );
  365.    }
  366.  
  367.    usReply = pMsg->usReply; /* now we can extract the reply */
  368.  
  369.    return( usReply );
  370.  
  371. } /* end MsgBox() */
  372.  
  373. /*********************************************************************/
  374. /* MsgBoxThread()                                                    */
  375. /*********************************************************************/
  376. VOID MsgBoxThread( PVOID arg )
  377. {
  378.    /*****************************************************/
  379.    /* There is never an owner for the message box,      */
  380.    /* we don't even know if there is message queue etc. */
  381.    /* so we create a thread and allocate a hab and hmq. */
  382.    /*****************************************************/
  383.  
  384.    USHORT usRC;
  385.    USHORT usAttrs;
  386.    PMYMSG pMsg;
  387.  
  388.    pMsg = (PMYMSG) arg;
  389.  
  390.    pMsg->habMyMsg = WinInitialize( NULLHANDLE );
  391.    if ( pMsg->habMyMsg != NULLHANDLE )
  392.    {
  393.       pMsg->hmqMyMsg = WinCreateMsgQueue( pMsg->habMyMsg, NULLHANDLE );
  394.       if ( pMsg->hmqMyMsg != NULLHANDLE )
  395.       {
  396.  
  397.          switch( pMsg->chIcon )
  398.          {
  399.             case 'N':
  400.             case 'n':
  401.                  usAttrs = MB_NOICON;
  402.                  break;
  403.             case 'I':
  404.             case 'i':
  405.                  usAttrs = MB_ICONASTERISK;
  406.                  break;
  407.             case 'W':
  408.             case 'w':
  409.                  usAttrs = MB_ICONEXCLAMATION;
  410.                  break;
  411.             case 'Q':
  412.             case 'q':
  413.                  usAttrs = MB_ICONQUESTION;
  414.                  break;
  415.             case 'S':
  416.             case 's':
  417.                  usAttrs = MB_ICONHAND;
  418.                  break;
  419.             default:
  420.                  usAttrs = MB_ICONHAND;
  421.                  break;
  422.          }
  423.  
  424.          switch( pMsg->chButtons )
  425.          {
  426.             case 'V':
  427.             case 'v':
  428.                  usAttrs |= MB_ENTER;
  429.                  break;
  430.             case 'I':
  431.             case 'i':
  432.                  usAttrs |= MB_OK;
  433.                  break;
  434.             case 'W':
  435.             case 'w':
  436.                  usAttrs |= MB_OKCANCEL;
  437.                  break;
  438.             case 'Q':
  439.             case 'q':
  440.                  usAttrs |= MB_YESNO;
  441.                  break;
  442.             case 'S':
  443.             case 's':
  444.                  usAttrs |= MB_CANCEL;
  445.                  break;
  446.             case 'R':
  447.             case 'r':
  448.                  usAttrs |= MB_RETRYCANCEL;
  449.                  break;
  450.             case 'A':
  451.             case 'a':
  452.                  usAttrs |= MB_ABORTRETRYIGNORE;
  453.                  break;
  454.             default:
  455.                  usAttrs |= MB_CANCEL;
  456.                  break;
  457.          }
  458.  
  459.          if (   (pMsg->usNumber != 0)
  460.              || (strchr(YES_OPTIONS, pMsg->chHelp) != NULL) )
  461.          {
  462.             usAttrs |= MB_HELP;
  463.          }
  464.  
  465.          usRC = WinMessageBox( HWND_DESKTOP,
  466.                                pMsg->hwndMyMsg,
  467.                                (PSZ) pMsg->szText,
  468.                                (PSZ) pMsg->szTitle,
  469.                                pMsg->usNumber,
  470.                                usAttrs |
  471.                                MB_MOVEABLE |
  472.                                MB_CUANOTIFICATION );
  473.          switch( usRC )
  474.          {
  475.             case MBID_OK:
  476.             case MBID_YES:
  477.             case MBID_ENTER:
  478.             case MBID_RETRY:
  479.                  pMsg->usReply = MSG_RESPONSE_OK;
  480.                  break;
  481.  
  482.             case MBID_CANCEL:
  483.             case MBID_NO:
  484.             case MBID_ERROR:
  485.             case MBID_ABORT:
  486.                  pMsg->usReply = MSG_RESPONSE_CANCEL;
  487.                  break;
  488.  
  489.             case MBID_HELP:
  490.                  pMsg->usReply = MSG_RESPONSE_HELP;
  491.                  break;
  492.  
  493.             default: /* MBID_IGNORE */
  494.                  pMsg->usReply = MSG_RESPONSE_IGNORE;
  495.                  break;
  496.          }
  497.  
  498.          WinDestroyMsgQueue( pMsg->hmqMyMsg );
  499.          pMsg->hmqMyMsg = NULLHANDLE;
  500.       }
  501.       WinTerminate( pMsg->habMyMsg );
  502.       pMsg->habMyMsg = NULLHANDLE;
  503.    }
  504.  
  505.    _endthread();
  506.  
  507. } /* end MsgBoxThread() */
  508.  
  509. /*********************************************************************/
  510. /* StripNulls()                                                      */
  511. /* Note: This function requires addition of DBCS handling so that    */
  512. /*       DBCS trail bytes are not stripped.                          */
  513. /*********************************************************************/
  514. VOID StripNulls( PSZ pszBuffer, PULONG pulLength )
  515. {
  516.    ULONG i, j;
  517.    i = 0;
  518.    for ( j=0; j < *pulLength; j++ ) {  /* for each character in buff */
  519.       if (pszBuffer[j] != EOSTR_CH) {  /* if it is not a null        */
  520.          pszBuffer[i] = pszBuffer[j];  /* then keep it               */
  521.          i++;                          /* and skip to next position  */
  522.       }
  523.    }
  524.    pszBuffer[i] = EOSTR_CH;            /* set the new end of string  */
  525.    *pulLength = i;                     /* set the new length         */
  526.    return;
  527. }
  528.  
  529. /*********************************************************************/
  530. /* ReplaceNulls()                                                    */
  531. /* Note: This function requires addition of DBCS handling so that    */
  532. /*       DBCS trail bytes are not replaced.                          */
  533. /*********************************************************************/
  534. VOID ReplaceNulls( PSZ pszBuffer, ULONG ulLength, BYTE bReplace )
  535. {
  536.    ULONG i;
  537.    for ( i=0; i < ulLength; i++ ) {    /* for each character in buff */
  538.       if (pszBuffer[i] == EOSTR_CH) {  /* if it is a null            */
  539.          pszBuffer[i] = bReplace;      /* then replace it            */
  540.       }
  541.    }
  542.    return;
  543. }
  544.  
  545. /*********************************************************************/
  546. /* END MODULE                                                        */
  547. /*********************************************************************/
  548.