home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rxasync2.zip / COMSFUNC.C next >
Text File  |  1994-12-26  |  47KB  |  978 lines

  1. /*****************************************************************************/
  2. /*                                                                           */
  3. /*  MODULE         COMSFUNC.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    Serial Communications Functions                           */
  11. /*                                                                           */
  12. /*  FUNCTIONS                                                                */
  13. /*                                                                           */
  14. /*    CallDevice     - Invoke specified ASYNC_IOCTL call                     */
  15. /*    ActiveSignal   - Return modem input/output signal status               */
  16. /*    FlushInput     - Flush device driver input queue                       */
  17. /*    FlushOutput    - Flush device driver output queue                      */
  18. /*                                                                           */
  19. /*    GetDcbInfo     - Get the device control block info                     */
  20. /*    SetDcbInfo     - Set the device control block info                     */
  21. /*    GetEnhParm     - Get the enhanced parameters                           */
  22. /*    SetEnhParm     - Set the enhanced parameters                           */
  23. /*    GetLnCtrl      - Get the comms port settings                           */
  24. /*    SetLnCtrl      - Set the comms port settings                           */
  25. /*    GetComStatus   - Get COM status                                        */
  26. /*    GetTxStatus    - Get Transmit status                                   */
  27. /*    GetModemOutput - Get modem output signals                              */
  28. /*    GetModemInput  - Get modem input signals                               */
  29. /*    SetBreakOff    - Set break signal off                                  */
  30. /*    SetBreakOn     - Set break signal on                                   */
  31. /*    TxImmediate    - Transmit specified byte immediately                   */
  32. /*    TxStop         - Stop transmission (ala XOFF)                          */
  33. /*    TxStart        - Start transmission (ala XON)                          */
  34. /*    SetMdmOutput   - Set modem output signals                              */
  35. /*    GetRxCount     - Get size and number of chars in RX queue              */
  36. /*    GetTxCount     - Get size and number of chars in TX queue              */
  37. /*    GetComError    - Get the COM Error Word                                */
  38. /*    GetComEvent    - Get the COM Event Word                                */
  39. /*                                                                           */
  40. /*    PrtDcbInfo     - Print DCB information to stdout                       */
  41. /*                                                                           */
  42. /*    WaitCarrier    - Wait/test for carrier signal                          */
  43. /*    WaitInput      - Wait/test for data input                              */
  44. /*    SendBreak      - Send break for specified duration                     */
  45. /*                                                                           */
  46. /*    OpenPort       - Open the specified comms port                         */
  47. /*    ClosePort      - Close the specified comms port                        */
  48. /*    WritePort      - Write the specified data to the comms port            */
  49. /*    ReadPort       - Read data from the specified comms port               */
  50. /*                                                                           */
  51. /*****************************************************************************/
  52.  
  53. /*********************************************************************/
  54. /* Includes needed by this module                                    */
  55. /*********************************************************************/
  56.  
  57. #define  _MT
  58. #define  _DLL
  59. #define  INCL_DOS
  60. #define  INCL_ERRORS
  61. #define  INCL_DOSDEVIOCTL
  62.  
  63. #include <os2.h>
  64. #include <stdio.h>
  65. #include <string.h>
  66. #include <stdlib.h>
  67. #include <memory.h>
  68.  
  69. #include "miscfunc.h"
  70. #include "comsfunc.h"
  71.  
  72. /*********************************************************************/
  73. /* CallDevice()                                                      */
  74. /*********************************************************************/
  75. APIRET CallDevice( HFILE hcomPort,
  76.                    ULONG ulCategory,
  77.                    ULONG ulFunction,
  78.                    PVOID pParameters,
  79.                    PVOID pDataPacket )
  80. {
  81.    APIRET       rc;                    /* Function return code       */
  82.    PVOID        pParmPkt;              /* DevIOCtl parm packet ptr   */
  83.    PVOID        pDataPkt;              /* DevIOCtl data packet ptr   */
  84.    ULONG        ulParmLen;             /* DevIOCtl parm pack length  */
  85.    ULONG        ulDataLen;             /* DevIOCtl data pack length  */
  86.    PULONG       pulParmLen;            /* DevIOCtl parm pack len ptr */
  87.    PULONG       pulDataLen;            /* DevIOCtl data pack len ptr */
  88.    ULONG        ulSaveLen;             /* Save the data pack length  */
  89.    BYTE         bGenParm;              /* General DevIOCtl parm pack */
  90.    BYTE         bGenData;              /* General DevIOCtl data pack */
  91.    rc = NO_ERROR;
  92.    ulParmLen  = 0;
  93.    ulDataLen  = 0;
  94.    pulParmLen = &ulParmLen;
  95.    pulDataLen = &ulDataLen;
  96.    ulSaveLen  = 0;
  97.    switch( ulCategory )
  98.    {
  99.       case IOCTL_ASYNC:
  100.            pParmPkt = pParameters;
  101.            pDataPkt = pDataPacket;
  102.            switch( ulFunction )
  103.            {
  104.               case ASYNC_GETBAUDRATE:
  105.                    ulDataLen = GETBAUDRATE_SIZE;
  106.                    break;
  107.               case ASYNC_SETBAUDRATE:
  108.                    ulParmLen = SETBAUDRATE_SIZE;
  109.                    break;
  110.               case ASYNC_GETLINECTRL:
  111.                    ulDataLen = GETLINECONTROL_SIZE;
  112.                    break;
  113.               case ASYNC_SETLINECTRL:
  114.                    ulParmLen = SETLINECONTROL_SIZE;
  115.                    break;
  116.               case ASYNC_GETEXTDRATE:
  117.                    ulDataLen = GETEXTDRATE_SIZE;
  118.                    break;
  119.               case ASYNC_SETEXTDRATE:
  120.                    ulParmLen = SETEXTDRATE_SIZE;
  121.                    break;
  122.               case ASYNC_TRANSMITIMM:
  123.                    ulParmLen = TRANSMITIMM_SIZE;
  124.                    break;
  125.               case ASYNC_SETBREAKON:
  126.                    ulDataLen = COMERROR_SIZE;
  127.                    break;
  128.               case ASYNC_SETBREAKOFF:
  129.                    ulDataLen = COMERROR_SIZE;
  130.                    break;
  131.               case ASYNC_SETMODEMCTRL:
  132.                    ulParmLen = MODEMSTATUS_SIZE;
  133.                    ulDataLen = COMERROR_SIZE;
  134.                    break;
  135.               case ASYNC_STARTTRANSMIT:
  136.                    break;
  137.               case ASYNC_STOPTRANSMIT:
  138.                    break;
  139.               case ASYNC_GETDCBINFO:
  140.                    ulDataLen = GETDCBINFO_SIZE;
  141.                    break;
  142.               case ASYNC_SETDCBINFO:
  143.                    ulParmLen = SETDCBINFO_SIZE;
  144.                    break;
  145.               case ASYNC_GETENHPARM:
  146.                    ulDataLen = GETENHPARM_SIZE;
  147.                    break;
  148.               case ASYNC_SETENHPARM:
  149.                    ulParmLen = SETENHPARM_SIZE;
  150.                    break;
  151.               case ASYNC_GETCOMMSTATUS:
  152.                    ulDataLen = GETCOMMSTATUS_SIZE;
  153.                    break;
  154.               case ASYNC_GETLINESTATUS:
  155.                    ulDataLen = GETLINESTATUS_SIZE;
  156.                    break;
  157.               case ASYNC_GETMODEMINPUT:
  158.                    ulDataLen = GETMODEMIO_SIZE;
  159.                    break;
  160.               case ASYNC_GETMODEMOUTPUT:
  161.                    ulDataLen = GETMODEMIO_SIZE;
  162.                    break;
  163.               case ASYNC_GETINQUECOUNT:
  164.                    ulDataLen = GETIOQUEUE_SIZE;
  165.                    break;
  166.               case ASYNC_GETOUTQUECOUNT:
  167.                    ulDataLen = GETIOQUEUE_SIZE;
  168.                    break;
  169.               case ASYNC_GETCOMMERROR:
  170.                    ulDataLen = COMERROR_SIZE;
  171.                    break;
  172.               case ASYNC_GETCOMMEVENT:
  173.                    ulDataLen = GETCOMMEVENT_SIZE;
  174.                    break;
  175.               default:
  176.                    rc = ERROR_INVALID_PARAMETER;
  177.                    break;
  178.            }
  179.            break;
  180.       case IOCTL_GENERAL:
  181.            pParmPkt = &bGenParm;
  182.            pDataPkt = &bGenData;
  183.            switch( ulFunction )
  184.            {
  185.               case DEV_FLUSHINPUT:
  186.                    ulParmLen = DEVFLUSHPRM_SIZE;
  187.                    ulDataLen = DEVFLUSHDAT_SIZE;
  188.                    break;
  189.               case DEV_FLUSHOUTPUT:
  190.                    ulParmLen = DEVFLUSHPRM_SIZE;
  191.                    ulDataLen = DEVFLUSHDAT_SIZE;
  192.                    break;
  193.               default:
  194.                    rc = ERROR_INVALID_PARAMETER;
  195.                    break;
  196.            }
  197.            break;
  198.       default:
  199.            rc = ERROR_INVALID_PARAMETER;
  200.            break;
  201.    }
  202.    if ( hcomPort == NULLHANDLE ) {
  203.       rc = ERROR_INVALID_PARAMETER;
  204.    }
  205.    if ( rc == NO_ERROR ) {
  206.       ulSaveLen = ulDataLen;
  207.       if (ulParmLen == 0) {
  208.          pParmPkt = NULL;
  209.          pulParmLen = NULL;
  210.       }
  211.       if (ulDataLen == 0) {
  212.          pDataPkt = NULL;
  213.          pulDataLen = NULL;
  214.       }
  215.       if (pDataPkt != NULL) {
  216.          memset( pDataPkt, (BYTE)0, ulDataLen );       /* zeroise it */
  217.       }
  218.       rc = DosDevIOCtl( hcomPort,                          /* HFILE  */
  219.                         ulCategory,                        /* ULONG  */
  220.                         ulFunction,                        /* ULONG  */
  221.                         pParmPkt,                          /* PVOID  */
  222.                         ulParmLen,                         /* ULONG  */
  223.                         pulParmLen,                        /* PULONG */
  224.                         pDataPkt,                          /* PVOID  */
  225.                         ulDataLen,                         /* ULONG  */
  226.                         pulDataLen );                      /* PULONG */
  227.       if ( rc == NO_ERROR ) {
  228.          if ( ulDataLen != ulSaveLen ) {
  229.             rc = ERROR_GEN_FAILURE;    /* Didn't return enough data  */
  230.          }
  231.       }
  232.       if ( rc != NO_ERROR ) {
  233.          fprintf( stdout,
  234.                   "DosDevIOCtl(0x%4.4lX,0x%4.4lX) failed with RC=%d.\r\n",
  235.                   ulCategory,
  236.                   ulFunction,
  237.                   rc );
  238.       }
  239.    }
  240.    return( rc );                       /* Return DosDevIOCtl result  */
  241. } /* end CallDevice() */
  242.  
  243. /*********************************************************************/
  244. /* ActiveSignal()                                                    */
  245. /*********************************************************************/
  246. APIRET ActiveSignal( HFILE hcomPort, BYTE bSignal )
  247. {
  248.    APIRET       rc;                    /* 0 if active, -2 if not     */
  249.    BYTE         bComSignals;           /* Modem Input/Output Signals */
  250.    switch( bSignal )
  251.    {
  252.      case DTR_ON:
  253.      case RTS_ON:
  254.           rc = CallDevice( hcomPort,
  255.                            IOCTL_ASYNC,
  256.                            ASYNC_GETMODEMOUTPUT,
  257.                            NULL,
  258.                            &bComSignals );
  259.           break;
  260.      case CTS_ON:
  261.      case DSR_ON:
  262.      case RI_ON:
  263.      case DCD_ON:
  264.           rc = CallDevice( hcomPort,
  265.                            IOCTL_ASYNC,
  266.                            ASYNC_GETMODEMINPUT,
  267.                            NULL,
  268.                            &bComSignals );
  269.           break;
  270.      default:
  271.           rc = ERROR_INVALID_PARAMETER;
  272.           break;
  273.    }
  274.    if ( rc == NO_ERROR )
  275.       if ( !(bComSignals & bSignal) )
  276.          rc = RC_ASYNC_NO_SIGNAL;
  277.    return( rc );                       /* Return DosDevIOCtl result  */
  278. } /* end ActiveSignal() */
  279.  
  280. /*********************************************************************/
  281. /* FlushInput()                                                      */
  282. /*********************************************************************/
  283. APIRET FlushInput( HFILE hcomPort )
  284. {
  285.    BYTE         bCommandInfo;          /* Device command information */
  286.    BYTE         bCommandAnsw;          /* Device command response    */
  287.    bCommandInfo = GENERAL_CMDINFO_NONE;
  288.    return( CallDevice( hcomPort,
  289.                        IOCTL_GENERAL,
  290.                        DEV_FLUSHINPUT,
  291.                        &bCommandInfo,
  292.                        &bCommandAnsw ) );/* Return DosDevIOCtl result*/
  293. } /* end FlushInput() */
  294.  
  295. /*********************************************************************/
  296. /* FlushOutput()                                                     */
  297. /*********************************************************************/
  298. APIRET FlushOutput( HFILE hcomPort )
  299. {
  300.    BYTE         bCommandInfo;          /* Device command information */
  301.    BYTE         bCommandAnsw;          /* Device command response    */
  302.    bCommandInfo = GENERAL_CMDINFO_NONE;
  303.    return( CallDevice( hcomPort,
  304.                        IOCTL_GENERAL,
  305.                        DEV_FLUSHOUTPUT,
  306.                        &bCommandInfo,
  307.                        &bCommandAnsw ) );/* Return DosDevIOCtl result*/
  308. } /* end FlushOutput() */
  309.  
  310. /*********************************************************************/
  311. /* GetDcbInfo()                                                      */
  312. /*********************************************************************/
  313. APIRET GetDcbInfo( HFILE hcomPort, PDCBINFO2 pdcbPortInfo )
  314. {
  315.    return( CallDevice( hcomPort,
  316.                        IOCTL_ASYNC,
  317.                        ASYNC_GETDCBINFO,
  318.                        NULL,
  319.                        pdcbPortInfo ) );/* Return DosDevIOCtl result */
  320. } /* end GetDcbInfo() */
  321.  
  322. /*********************************************************************/
  323. /* SetDcbInfo()                                                      */
  324. /*********************************************************************/
  325. APIRET SetDcbInfo( HFILE hcomPort, PDCBINFO2 pdcbPortInfo )
  326. {
  327.    return( CallDevice( hcomPort,
  328.                        IOCTL_ASYNC,
  329.                        ASYNC_SETDCBINFO,
  330.                        pdcbPortInfo,
  331.                        NULL ) );       /* Return DosDevIOCtl result  */
  332. } /* end SetDcbInfo() */
  333.  
  334. /*********************************************************************/
  335. /* GetEnhParm()                                                      */
  336. /*********************************************************************/
  337. APIRET GetEnhParm( HFILE hcomPort, PBYTE pbEnhancedFlags )
  338. {
  339.    APIRET   rc;                        /* Function return code       */
  340.    ENHPARM  eparmParms;                /* Enhanced Mode Parameters   */
  341.    if ( pbEnhancedFlags == NULL ) {
  342.       rc = ERROR_INVALID_PARAMETER;
  343.    } else {
  344.       rc = CallDevice( hcomPort,
  345.                        IOCTL_ASYNC,
  346.                        ASYNC_GETENHPARM,
  347.                        NULL,
  348.                        &eparmParms );
  349.       if ( rc == NO_ERROR ) {
  350.          *pbEnhancedFlags = eparmParms.bEnhancedFlags;
  351.       }
  352.    }
  353.    return( rc );                       /* Return DosDevIOCtl result  */
  354. } /* end GetEnhParm() */
  355.  
  356. /*********************************************************************/
  357. /* SetEnhParm()                                                      */
  358. /*********************************************************************/
  359. APIRET SetEnhParm( HFILE hcomPort, BYTE bEnhancedFlags )
  360. {
  361.    APIRET   rc;                        /* Function return code       */
  362.    ENHPARM  eparmParms;                /* Enhanced Mode Parameters   */
  363.    rc = CallDevice( hcomPort,
  364.                     IOCTL_ASYNC,
  365.                     ASYNC_GETENHPARM,
  366.                     NULL,
  367.                     &eparmParms );
  368.    if ( rc == NO_ERROR ) {
  369.       if ( eparmParms.bEnhancedFlags & MODE_ENH_SUPPORTED ) {
  370.          eparmParms.bEnhancedFlags = bEnhancedFlags;
  371.          rc = CallDevice( hcomPort,
  372.                           IOCTL_ASYNC,
  373.                           ASYNC_SETENHPARM,
  374.                           &eparmParms,
  375.                           NULL );
  376.       } else {
  377.          /* don't attempt setting, as enhanced mode is not supported */
  378.       }
  379.    }
  380.    return( rc );                       /* Return DosDevIOCtl result  */
  381. } /* end SetEnhParm() */
  382.  
  383. /*********************************************************************/
  384. /* GetLnCtrl()                                                       */
  385. /*********************************************************************/
  386. APIRET GetLnCtrl( HFILE hcomPort, PEXTDRATE perateBaudRate, PLINECONTROL plnctlLineControl )
  387. {
  388.    APIRET   rc;                        /* Function return code       */
  389.    rc = CallDevice( hcomPort,
  390.                     IOCTL_ASYNC,
  391.                     ASYNC_GETEXTDRATE,
  392.                     NULL,
  393.                     perateBaudRate );
  394.    if ( rc == NO_ERROR ) {
  395.       rc = CallDevice( hcomPort,
  396.                        IOCTL_ASYNC,
  397.                        ASYNC_GETLINECTRL,
  398.                        NULL,
  399.                        plnctlLineControl );
  400.    }
  401.    return( rc );                       /* Return DosDevIOCtl result  */
  402. } /* end GetLnCtrl() */
  403.  
  404. /*********************************************************************/
  405. /* SetLnCtrl()                                                       */
  406. /*********************************************************************/
  407. APIRET SetLnCtrl( HFILE hcomPort, PEXTDRATE perateBaudRate, PLINECONTROL plnctlLineControl )
  408. {
  409.    APIRET   rc;                        /* Function return code       */
  410.    rc = CallDevice( hcomPort,
  411.                     IOCTL_ASYNC,
  412.                     ASYNC_SETEXTDRATE,
  413.                     perateBaudRate,
  414.                     NULL );
  415.    if ( rc == NO_ERROR ) {
  416.       rc = CallDevice( hcomPort,
  417.                        IOCTL_ASYNC,
  418.                        ASYNC_SETLINECTRL,
  419.                        plnctlLineControl,
  420.                        NULL );
  421.    }
  422.    return( rc );                       /* Return DosDevIOCtl result  */
  423. } /* end SetLnCtrl() */
  424.  
  425. /*********************************************************************/
  426. /* GetComStatus()                                                    */
  427. /*********************************************************************/
  428. APIRET GetComStatus( HFILE hcomPort, PBYTE pbComStatus )
  429. {
  430.    return( CallDevice( hcomPort,
  431.                        IOCTL_ASYNC,
  432.                        ASYNC_GETCOMMSTATUS,
  433.                        NULL,
  434.                        pbComStatus ) );/* Return DosDevIOCtl result  */
  435. } /* end GetComStatus() */
  436.  
  437. /*********************************************************************/
  438. /* GetTxStatus()                                                     */
  439. /*********************************************************************/
  440. APIRET GetTxStatus( HFILE hcomPort, PBYTE pbTxStatus )
  441. {
  442.    return( CallDevice( hcomPort,
  443.                        IOCTL_ASYNC,
  444.                        ASYNC_GETLINESTATUS,
  445.                        NULL,
  446.                        pbTxStatus ) ); /* Return DosDevIOCtl result  */
  447. } /* end GetTxStatus() */
  448.  
  449. /*********************************************************************/
  450. /* GetModemOutput()                                                  */
  451. /*********************************************************************/
  452. APIRET GetModemOutput( HFILE hcomPort, PBYTE pbMdmOutput )
  453. {
  454.    return( CallDevice( hcomPort,
  455.                        IOCTL_ASYNC,
  456.                        ASYNC_GETMODEMOUTPUT,
  457.                        NULL,
  458.                        pbMdmOutput ) );/* Return DosDevIOCtl result  */
  459. } /* end GetModemOutput() */
  460.  
  461. /*********************************************************************/
  462. /* GetModemInput()                                                   */
  463. /*********************************************************************/
  464. APIRET GetModemInput( HFILE hcomPort, PBYTE pbMdmInput )
  465. {
  466.    return( CallDevice( hcomPort,
  467.                        IOCTL_ASYNC,
  468.                        ASYNC_GETMODEMINPUT,
  469.                        NULL,
  470.                        pbMdmInput ) ); /* Return DosDevIOCtl result  */
  471. } /* end GetModemInput() */
  472.  
  473. /*********************************************************************/
  474. /* SetBreakOff()                                                     */
  475. /*********************************************************************/
  476. APIRET SetBreakOff( HFILE hcomPort )
  477. {
  478.    COMERR   ComError;                  /* Communication Error Status */
  479.    return( CallDevice( hcomPort,
  480.                        IOCTL_ASYNC,
  481.                        ASYNC_SETBREAKOFF,
  482.                        NULL,
  483.                        &ComError ) );  /* Return DosDevIOCtl result  */
  484. } /* end SetBreakOff() */
  485.  
  486. /*********************************************************************/
  487. /* SetBreakOn()                                                      */
  488. /*********************************************************************/
  489. APIRET SetBreakOn( HFILE hcomPort )
  490. {
  491.    COMERR   ComError;                  /* Communication Error Status */
  492.    return( CallDevice( hcomPort,
  493.                        IOCTL_ASYNC,
  494.                        ASYNC_SETBREAKON,
  495.                        NULL,
  496.                        &ComError ) );  /* Return DosDevIOCtl result  */
  497. } /* end SetBreakOn() */
  498.  
  499. /*********************************************************************/
  500. /* TxImmediate()                                                     */
  501. /*********************************************************************/
  502. APIRET TxImmediate( HFILE hcomPort, BYTE bAnyByte )
  503. {
  504.    return( CallDevice( hcomPort,
  505.                        IOCTL_ASYNC,
  506.                        ASYNC_TRANSMITIMM,
  507.                        &bAnyByte,
  508.                        NULL ) );       /* Return DosDevIOCtl result  */
  509. } /* end TxImmediate() */
  510.  
  511. /*********************************************************************/
  512. /* TxStop()                                                          */
  513. /*********************************************************************/
  514. APIRET TxStop( HFILE hcomPort )
  515. {
  516.    return( CallDevice( hcomPort,
  517.                        IOCTL_ASYNC,
  518.                        ASYNC_STOPTRANSMIT,
  519.                        NULL,
  520.                        NULL ) );       /* Return DosDevIOCtl result  */
  521. } /* end TxStop() */
  522.  
  523. /*********************************************************************/
  524. /* TxStart()                                                         */
  525. /*********************************************************************/
  526. APIRET TxStart( HFILE hcomPort )
  527. {
  528.    return( CallDevice( hcomPort,
  529.                        IOCTL_ASYNC,
  530.                        ASYNC_STARTTRANSMIT,
  531.                        NULL,
  532.                        NULL ) );       /* Return DosDevIOCtl result  */
  533. } /* end TxStart() */
  534.  
  535. /*********************************************************************/
  536. /* SetMdmOutput()                                                    */
  537. /*********************************************************************/
  538. APIRET SetMdmOutput( HFILE hcomPort, BYTE bModemOn, BYTE bModemOff )
  539. {
  540.    MODEMSTATUS mdmstControl;           /* Modem control              */
  541.    COMERR      ComError;               /* Communication Error Status */
  542.    mdmstControl.fbModemOn  = bModemOn;
  543.    mdmstControl.fbModemOff = bModemOff;
  544.    return( CallDevice( hcomPort,
  545.                        IOCTL_ASYNC,
  546.                        ASYNC_SETMODEMCTRL,
  547.                        &mdmstControl,
  548.                        &ComError ) );  /* Return DosDevIOCtl result  */
  549. } /* end SetMdmOutput() */
  550.  
  551. /*********************************************************************/
  552. /* GetRxCount()                                                      */
  553. /*********************************************************************/
  554. APIRET GetRxCount( HFILE hcomPort, PUSHORT pusRxCount, PUSHORT pusRxSize )
  555. {
  556.    APIRET   rc;                        /* Function return code       */
  557.    IOQUEUE  ioqueStatus;               /* IO Queue details returned  */
  558.    if ( (pusRxCount == NULL) || (pusRxSize  == NULL) ) {
  559.       rc = ERROR_INVALID_PARAMETER;
  560.    } else {
  561.       rc = CallDevice( hcomPort,
  562.                        IOCTL_ASYNC,
  563.                        ASYNC_GETINQUECOUNT,
  564.                        NULL,
  565.                        &ioqueStatus );
  566.       if ( rc == NO_ERROR ) {
  567.          *pusRxCount = ioqueStatus.usQueueCount;
  568.          *pusRxSize  = ioqueStatus.usQueueSize;
  569.       }
  570.    }
  571.    return( rc );                       /* Return DosDevIOCtl result  */
  572. } /* end GetRxCount() */
  573.  
  574. /*********************************************************************/
  575. /* GetTxCount()                                                      */
  576. /*********************************************************************/
  577. APIRET GetTxCount( HFILE hcomPort, PUSHORT pusTxCount, PUSHORT pusTxSize )
  578. {
  579.    APIRET   rc;                        /* Function return code       */
  580.    IOQUEUE  ioqueStatus;               /* IO Queue details returned  */
  581.    if ( (pusTxCount == NULL) || (pusTxSize  == NULL) ) {
  582.       rc = ERROR_INVALID_PARAMETER;
  583.    } else {
  584.       rc = CallDevice( hcomPort,
  585.                        IOCTL_ASYNC,
  586.                        ASYNC_GETOUTQUECOUNT,
  587.                        NULL,
  588.                        &ioqueStatus );
  589.       if ( rc == NO_ERROR ) {
  590.          *pusTxCount = ioqueStatus.usQueueCount;
  591.          *pusTxSize  = ioqueStatus.usQueueSize;
  592.       }
  593.    }
  594.    return( rc );                       /* Return DosDevIOCtl result  */
  595. } /* end GetTxCount() */
  596.  
  597. /*********************************************************************/
  598. /* GetComError()                                                     */
  599. /*********************************************************************/
  600. APIRET GetComError( HFILE hcomPort, PUSHORT pusComError )
  601. {
  602.    return( CallDevice( hcomPort,
  603.                        IOCTL_ASYNC,
  604.                        ASYNC_GETCOMMERROR,
  605.                        NULL,
  606.                        pusComError ) );/* Return DosDevIOCtl result  */
  607. } /* end GetComError() */
  608.  
  609. /*********************************************************************/
  610. /* GetComEvent()                                                     */
  611. /*********************************************************************/
  612. APIRET GetComEvent( HFILE hcomPort, PUSHORT pusComEvent )
  613. {
  614.    return( CallDevice( hcomPort,
  615.                        IOCTL_ASYNC,
  616.                        ASYNC_GETCOMMEVENT,
  617.                        NULL,
  618.                        pusComEvent ) );/* Return DosDevIOCtl result  */
  619. } /* end GetComEvent() */
  620.  
  621. /*********************************************************************/
  622. /* PrtDcbInfo()                                                      */
  623. /*********************************************************************/
  624. APIRET PrtDcbInfo( HFILE hcomPort )
  625. {
  626.    APIRET   rc;                        /* Function return code       */
  627.    DCBINFO2 dcbPortInfo;               /* Device control block       */
  628.    rc = CallDevice( hcomPort, IOCTL_ASYNC, ASYNC_GETDCBINFO, NULL, &dcbPortInfo );
  629.    fprintf( stdout, "Current DCBINFO settings:\r\n" );
  630.    fprintf( stdout, "\r\n" );
  631.    fprintf( stdout, "Write Timeout  =>%u<\r\n",      dcbPortInfo.usWriteTimeout );
  632.    fprintf( stdout, "Read Timeout   =>%u<\r\n",      dcbPortInfo.usReadTimeout );
  633.    fprintf( stdout, "Hand Shake     =>0x%2.2X<\r\n", dcbPortInfo.fbCtlHndShake );
  634.    fprintf( stdout, "Flow Replace   =>0x%2.2X<\r\n", dcbPortInfo.fbFlowReplace );
  635.    fprintf( stdout, "Timeout        =>0x%2.2X<\r\n", dcbPortInfo.fbTimeout );
  636.    fprintf( stdout, "Error Replace  =>0x%2.2X<\r\n", dcbPortInfo.bErrorReplacementChar );
  637.    fprintf( stdout, "Break Replace  =>0x%2.2X<\r\n", dcbPortInfo.bBreakReplacementChar );
  638.    fprintf( stdout, "XON Character  =>0x%2.2X<\r\n", dcbPortInfo.bXONChar );
  639.    fprintf( stdout, "XOFF Character =>0x%2.2X<\r\n", dcbPortInfo.bXOFFChar );
  640.    fprintf( stdout, "\r\n" );
  641.    return( rc );
  642. } /* end PrtDcbInfo() */
  643.  
  644. /*********************************************************************/
  645. /* WaitCarrier()                                                     */
  646. /*********************************************************************/
  647. APIRET WaitCarrier(
  648.           HFILE    hcomPort,           /* Communications port handle */
  649.           LONG     lTimeLimit          /* Wait timeout limit         */
  650.        )
  651. {
  652.    APIRET       rc;                    /* 0 DCD, -1 timeout, -2 noDCD*/
  653.    BYTE         bComInput;             /* Modem Input Signals        */
  654.    BOOL         fTimedOut;             /* Function has timed out     */
  655.    LONG         lElapsed;              /* Time elapsed in millisecs  */
  656.    DATETIME     tTimeStart;            /* Timer start time           */
  657.    DATETIME     tTimeNow;              /* Time now                   */
  658.    fTimedOut = FALSE;
  659.    DosGetDateTime( &tTimeStart );
  660.    do {
  661.       rc = GetModemInput( hcomPort, &bComInput ); /* check mdm input */
  662.       if ( rc != NO_ERROR ) {               /* get modeminput failed */
  663.          fTimedOut = TRUE;                  /* implicit timeout      */
  664.       } else if ( bComInput & DCD_ON ) {    /* carrier was detected  */
  665.          fTimedOut = TRUE;                  /* implicit timeout      */
  666.       } else if ( lTimeLimit == 0 ) {       /* no waiting            */
  667.          rc = RC_ASYNC_NO_SIGNAL;           /* force no_signal return*/
  668.          fTimedOut = TRUE;                  /* implicit timeout      */
  669.       } else if ( lTimeLimit < 0 ) {        /* wait forever          */
  670.          DosSleep( MAX_SLEEP );             /* Wait 1/100th second   */
  671.       } else {                              /* check for timeout     */
  672.          DosGetDateTime( &tTimeNow );
  673.          lElapsed = MyDiffTime( &tTimeNow, &tTimeStart );
  674.          if ( lElapsed > lTimeLimit ) {     /* we really did         */
  675.             rc = RC_ASYNC_TIMED_OUT;        /* force timed_out return*/
  676.             fTimedOut = TRUE;               /* explicit timeout      */
  677.          } else {                           /* keep waiting          */
  678.             DosSleep( MAX_SLEEP );          /* Wait 1/100th second   */
  679.          }
  680.       }
  681.    } while( !fTimedOut );
  682.    return( rc );                       /* Return DosDevIOCtl result  */
  683. } /* end WaitCarrier() */
  684.  
  685. /*********************************************************************/
  686. /* WaitInput()                                                       */
  687. /*********************************************************************/
  688. APIRET WaitInput(
  689.           HFILE    hcomPort,           /* Communications port handle */
  690.           LONG     lTimeLimit          /* Wait timeout limit         */
  691.        )
  692. {
  693.    APIRET       rc;                    /* 0 data, -1 timeout, -3 none*/
  694.    USHORT       usComEvent;            /* COM Event Information      */
  695.    BOOL         fTimedOut;             /* Function has timed out     */
  696.    LONG         lElapsed;              /* Time elapsed in millisecs  */
  697.    DATETIME     tTimeStart;            /* Timer start time           */
  698.    DATETIME     tTimeNow;              /* Time now                   */
  699.    fTimedOut = FALSE;
  700.    DosGetDateTime( &tTimeStart );
  701.    do {
  702.       rc = GetComEvent( hcomPort, &usComEvent ); /* check com event  */
  703.       if ( rc != NO_ERROR ) {               /* get commevent failed  */
  704.          fTimedOut = TRUE;                  /* implicit timeout      */
  705.       } else if ( usComEvent & CHAR_RECEIVED ) { /* got some data ok */
  706.          fTimedOut = TRUE;                  /* implicit timeout      */
  707.       } else if ( lTimeLimit == 0 ) {       /* no waiting            */
  708.          rc = RC_ASYNC_NO_INPUT;            /* force no_input return */
  709.          fTimedOut = TRUE;                  /* implicit timeout      */
  710.       } else if ( lTimeLimit < 0 ) {        /* wait forever          */
  711.          DosSleep( MAX_SLEEP );             /* Wait 1/100th second   */
  712.       } else {                              /* check for timeout     */
  713.          DosGetDateTime( &tTimeNow );
  714.          lElapsed = MyDiffTime( &tTimeNow, &tTimeStart );
  715.          if ( lElapsed > lTimeLimit ) {     /* we really did         */
  716.             rc = RC_ASYNC_TIMED_OUT;        /* force timed_out return*/
  717.             fTimedOut = TRUE;               /* explicit timeout      */
  718.          } else {                           /* keep waiting          */
  719.             DosSleep( MAX_SLEEP );          /* Wait 1/100th second   */
  720.          }
  721.       }
  722.    } while( !fTimedOut );
  723.    return( rc );                       /* Return DosDevIOCtl result  */
  724. } /* end WaitInput() */
  725.  
  726. /*********************************************************************/
  727. /* SendBreak()                                                       */
  728. /*********************************************************************/
  729. APIRET SendBreak(
  730.           HFILE    hcomPort,           /* Communications port handle */
  731.           ULONG    ulDuration          /* Break duration             */
  732.        )
  733. {
  734.    APIRET   rc1;                       /* Function return code       */
  735.    APIRET   rc2;                       /* Function return code       */
  736.    rc1 = SetBreakOn( hcomPort );
  737.    if ( rc1 == NO_ERROR ) {
  738.       if ( ulDuration > 0 ) {          /* Only if its worthwile      */
  739.          DosSleep( ulDuration );
  740.       }
  741.    }
  742.    rc2 = SetBreakOff( hcomPort );
  743.    if ( rc2 != NO_ERROR ) {
  744.       if ( rc1 == NO_ERROR ) {         /* Not already in error       */
  745.          rc1 = rc2;
  746.       }
  747.    }
  748.    return( rc1 );                      /* Return DosDevIOCtl result  */
  749. } /* end SendBreak() */
  750.  
  751. /*********************************************************************/
  752. /* OpenPort()                                                        */
  753. /*********************************************************************/
  754. APIRET OpenPort(
  755.           PSZ      pszName,            /* Communications port name   */
  756.           PHFILE   phcomPort           /* Communications port handle */
  757.        )
  758. {
  759.    APIRET   rc;                        /* Function return code       */
  760.    ULONG    ulOpenAction;              /* Open action                */
  761.    *phcomPort = NULLHANDLE;
  762.    rc = DosOpen( pszName,
  763.                  phcomPort,
  764.                  &ulOpenAction,
  765.                  0,
  766.                  FILE_NORMAL,
  767.                  FILE_OPEN,
  768.                  OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE,
  769.                  (PEAOP2) NULL );
  770.    if ( rc != NO_ERROR ) {             /* Couldn't open port         */
  771.       fprintf( stdout, "DosOpen(%s) failed with RC=%d.\r\n", pszName, rc );
  772.       *phcomPort = NULLHANDLE;
  773.    }
  774.    return( rc );                       /* Return DosOpen result      */
  775. } /* end OpenPort() */
  776.  
  777. /*********************************************************************/
  778. /* ClosePort()                                                       */
  779. /*********************************************************************/
  780. APIRET ClosePort(
  781.           PHFILE   phcomPort           /* Communications port handle */
  782.        )
  783. {
  784.    APIRET   rc;                        /* Function return code       */
  785.    rc = DosClose( *phcomPort );
  786.    if ( rc != NO_ERROR ) {
  787.       fprintf( stdout, "DosClose(%d) failed with RC=%d.\r\n", *phcomPort, rc );
  788.    }
  789.    *phcomPort = NULLHANDLE;
  790.    return( rc );                       /* Return DosClose result     */
  791. } /* end ClosePort() */
  792.  
  793. /*********************************************************************/
  794. /* WritePort()                                                       */
  795. /*********************************************************************/
  796. APIRET WritePort(
  797.           HFILE    hcomPort,           /* Communications port handle */
  798.           PSZ      pszBuffer,          /* Buffer of data to write    */
  799.           ULONG    ulBuffLen,          /* Length of data in buffer   */
  800.           PULONG   pulRemains          /* Amount unwritten           */
  801.        )
  802. {
  803.    APIRET   rc;                        /* Function return code       */
  804.    ULONG    ulWritten;                 /* Number of chars written    */
  805.    ulWritten = 0;
  806.    if ( ulBuffLen > 0 ) {              /* Not empty buffer           */
  807.       rc = DosWrite( hcomPort, pszBuffer, ulBuffLen, &ulWritten );
  808.       if ( rc != NO_ERROR ) {
  809.          fprintf( stdout, "DosWrite(%s) failed with RC=%d.\r\n", pszBuffer, rc );
  810.       }
  811.    }
  812.    *pulRemains = ulBuffLen - ulWritten;
  813.    return( rc );                       /* Return DosWrite result     */
  814. } /* end WritePort() */
  815.  
  816. /*********************************************************************/
  817. /* ReadPort()                                                        */
  818. /*                                                                   */
  819. /* Note:                                                             */
  820. /*                                                                   */
  821. /*   This routine requires DBCS handling so that DBCS trail bytes    */
  822. /*   are not inadvertantly stripped if the ReadSize should cause     */
  823. /*   a break within the DBCS pair and the trail byte of the DBCS     */
  824. /*   character just happens to be 0x00.                              */
  825. /*                                                                   */
  826. /*   pulBuffLen indicates the total amount requested to be read in   */
  827. /*   ulReadSize chunks, the total amount actually read is returned   */
  828. /*   in pulBuffLen.                                                  */
  829. /*                                                                   */
  830. /*   pszNullReplace and pszLineEnd must at this time be single       */
  831. /*   character strings.                                              */
  832. /*                                                                   */
  833. /*********************************************************************/
  834. APIRET ReadPort( HFILE  hcomPort,      /* Communications port handle */
  835.                  PBYTE  pbReadBuff,    /* Buffer to read data with   */
  836.                  ULONG  ulReadSize,    /* Block size to use          */
  837.                  PBYTE  pbBuffer,      /* Buffer to return data in   */
  838.                  PULONG pulBuffLen,    /* Length of data to read     */
  839.                  LONG   lTimeLimit,    /* Time limit to use, if any  */
  840.                  PSZ    pszNullReplace,/* Null replace char, if any  */
  841.                  PSZ    pszLineEnd )   /* Line end char, if any      */
  842. {
  843.    APIRET       rc;                    /* Function return code       */
  844.    USHORT       usComEvent;            /* COM Event Information      */
  845.    BOOL         fWaitForMore;          /* Poll for more input        */
  846.    BOOL         fTimedOut;             /* Function has timed out     */
  847.    BOOL         fStopReading;          /* Got all we wanted flag     */
  848.    BOOL         fByteFound;            /* Found some data to read    */
  849.    ULONG        ulNumToRead;           /* Number to read this time   */
  850.    ULONG        ulActuallyRead;        /* Number of chars we did get */
  851.    ULONG        ulTotalRead;           /* Total number of chars read */
  852.    LONG         lElapsed;              /* Time elapsed in millisecs  */
  853.    DATETIME     tTimeStart;            /* Timer start time           */
  854.    DATETIME     tTimeNow;              /* Time now                   */
  855.    BOOL         fWantNulls;            /* Whether to keep nulls      */
  856.    BYTE         bNullReplace;          /* Byte to use inplace of null*/
  857.    BYTE         bLineEnd;              /* Byte to use in line end    */
  858.    DosGetDateTime( &tTimeStart );
  859.    ulTotalRead  = 0;
  860.    fTimedOut    = FALSE;
  861.    fStopReading = FALSE;
  862.    fWantNulls   = TRUE;
  863.    bNullReplace = EOSTR_CH;
  864.    if ( pszNullReplace != NULL ) {
  865.       fWantNulls   = FALSE;
  866.       bNullReplace = pszNullReplace[0];
  867.    }
  868.    bLineEnd = LINEFEED_CH;
  869.    if ( pszLineEnd != NULL ) {
  870.       if ( pszLineEnd[0] != EOSTR_CH ) {
  871.          bLineEnd = pszLineEnd[0];
  872.       }
  873.    }
  874.    if ( ulReadSize > 0 ) {             /* block mode */
  875.       ulNumToRead = ulReadSize;
  876.    } else  {                           /* line mode  */
  877.       ulNumToRead = 1;
  878.    }
  879.    if ( ulReadSize > *pulBuffLen ) {
  880.       rc = ERROR_INVALID_PARAMETER;
  881.    } else {
  882.       rc = GetComEvent( hcomPort, &usComEvent ); /* clear comm event word */
  883.       if ( rc == NO_ERROR ) {
  884.          do {
  885.             fWaitForMore = FALSE;
  886.             do {
  887.                ulActuallyRead = 0;
  888.                memset( pbReadBuff, (BYTE)0, ulNumToRead ); /* zeroise read buffer */
  889.                rc = DosRead( hcomPort, pbReadBuff, (ULONG) ulNumToRead, &ulActuallyRead );
  890.                if ( (rc == NO_ERROR) || (rc == ERROR_MORE_DATA) ) {
  891.                   if ( ulActuallyRead != ulNumToRead ) {
  892.                      fWaitForMore = TRUE;
  893.                   }
  894.                   if ( ulActuallyRead > 0 ) {
  895.                      if ( !fWantNulls ) {
  896.                         if ( bNullReplace != EOSTR_CH ) {
  897.                            ReplaceNulls( pbReadBuff, ulActuallyRead, bNullReplace );
  898.                         } else {
  899.                            StripNulls( pbReadBuff, &ulActuallyRead );
  900.                         }
  901.                      }
  902.                      if ( ulActuallyRead > 0 ) {
  903.                         memcpy( &(pbBuffer[ulTotalRead]), pbReadBuff, ulActuallyRead );
  904.                         ulTotalRead = ulTotalRead + ulActuallyRead;
  905.                         if ( ulReadSize > 0 ) {           /* block mode */
  906.                            /* number to read is the amount left unread  */
  907.                            /* or the block size if that is the lesser.  */
  908.                            ulNumToRead = *pulBuffLen - ulTotalRead;
  909.                            if ( ulReadSize < ulNumToRead ) {
  910.                               ulNumToRead = ulReadSize;
  911.                            }
  912.                            if ( ulNumToRead <= 0 ) {
  913.                               fStopReading = TRUE;
  914.                            }
  915.                         } else {                          /* line mode  */
  916.                            pbBuffer[ulTotalRead] = EOSTR_CH; /* terminate string */
  917.                            /* handle line termination detection */
  918.                            if (   (pbReadBuff[0] == LINEFEED_CH)    /* LINEFEED */
  919.                                || (pbReadBuff[0] == FORMFEED_CH)    /* FORMFEED */
  920.                                || (pbReadBuff[0] == EOFILE_CH)      /* EOF      */
  921.                                || (pbReadBuff[0] == bLineEnd)   ) { /* user spec*/
  922.                               fStopReading = TRUE;
  923.                            } else if ( ulTotalRead >= *pulBuffLen - 1 ) {
  924.                               /* stop one byte short to maintain string terminator */
  925.                               fStopReading = TRUE;
  926.                            }
  927.                         }
  928.                      } else if ( fWaitForMore ) {
  929.                         /* didn't receive enough data, wait for more */
  930.                      } else if ( lTimeLimit < 0) {
  931.                         /* read again, don't care about timeout */
  932.                      } else {
  933.                         DosGetDateTime( &tTimeNow );
  934.                         lElapsed = MyDiffTime( &tTimeNow, &tTimeStart );
  935.                         if ( lElapsed > lTimeLimit ) {       /* explicit timeout */
  936.                            rc = RC_ASYNC_TIMED_OUT;          /* so return timeout*/
  937.                            fTimedOut = TRUE;
  938.                         }
  939.                      }
  940.                   } /* some if not all data WAS read */
  941.                } else {
  942.                   fprintf( stdout, "DosRead() failed with RC=%d.\r\n", rc );
  943.                   fTimedOut = TRUE;                          /* implicit timeout */
  944.                }
  945.             } while( !fStopReading && !fTimedOut && !fWaitForMore );
  946.             if ( fWaitForMore ) {
  947.                fByteFound = FALSE;
  948.                do {
  949.                   rc = GetComEvent( hcomPort, &usComEvent ); /* check com event  */
  950.                   if ( rc != NO_ERROR ) {                    /* call failed      */
  951.                      fTimedOut = TRUE;                       /* implicit timeout */
  952.                   } else if ( usComEvent & CHAR_RECEIVED ) { /* got some data    */
  953.                      fByteFound = TRUE;                      /* exit wait loop   */
  954.                   } else if ( lTimeLimit < 0 ) {             /* waiting forever  */
  955.                      DosSleep( MAX_SLEEP );                  /* wait 1/100th sec */
  956.                   } else {                                   /* check timeout    */
  957.                      DosGetDateTime( &tTimeNow );
  958.                      lElapsed = MyDiffTime( &tTimeNow, &tTimeStart );
  959.                      if ( lElapsed > lTimeLimit ) {          /* limit exceeded   */
  960.                         rc = RC_ASYNC_TIMED_OUT;             /* so return timeout*/
  961.                         fTimedOut = TRUE;                    /* explicit timeout */
  962.                      } else {
  963.                         DosSleep( MAX_SLEEP );               /* wait 1/100th sec */
  964.                      }
  965.                   }
  966.                } while( !fByteFound && !fTimedOut );
  967.             } /* endif wait for more data to arrive */
  968.          } while( !fStopReading && !fTimedOut );
  969.       } /* endif get comm event okay */
  970.    } /* endif read size okay */
  971.    *pulBuffLen = ulTotalRead;                                /* return true length */
  972.    return( rc );
  973. } /* end ReadPort() */
  974.  
  975. /*********************************************************************/
  976. /* END MODULE                                                        */
  977. /*********************************************************************/
  978.