home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / rexx / api / devinfo / devinfo.c next >
C/C++ Source or Header  |  1999-05-11  |  14KB  |  268 lines

  1. /*******************************************************************/
  2. /*                                                                 */
  3. /* Module Name:        DEVINFO.C                                   */
  4. /*                                                                 */
  5. /* Description:        Provide access to system device             */
  6. /*                     device configuration information from REXX  */
  7. /*                     programs.  The information is obtained from */
  8. /*                     DosDevConfig.                               */
  9. /*                                                                 */
  10. /* Function:           Call DosDevConfig and store information     */
  11. /*                     in the REXX program through the REXX        */
  12. /*                     Variable Pool Interface (RexxVariablePool). */
  13. /*                                                                 */
  14. /* Entry point:        DevInfo                                     */
  15. /*                                                                 */
  16. /* Notes:                                                          */
  17. /*                                                                 */
  18. /*   The entry point obeys the calling conventions for REXX        */
  19. /*   subcommand handlers.                                          */
  20. /*                                                                 */
  21. /*******************************************************************/
  22.  
  23. /*******************************************************************/
  24. /*                                                                 */
  25. /* Include files.  We use the following:                           */
  26. /*                                                                 */
  27. /*    REXXSAA.H         REXX specific type definitions and         */
  28. /*                      function prototypes.                       */
  29. /*                                                                 */
  30. /*    OS2.H             OS/2 specific type definitions and         */
  31. /*                      function prototypes.                       */
  32. /*                                                                 */
  33. /*    stdio.h           Standard C library I/O function prototypes.*/
  34. /*                                                                 */
  35. /*    stdlib.h          Standard C library function prototypes.    */
  36. /*                                                                 */
  37. /*    string.h          Standard C library string function         */
  38. /*                      prototypes.                                */
  39. /*                                                                 */
  40. /*******************************************************************/
  41.  
  42.  
  43. #define     INCL_DOSDEVICES
  44. #include    <os2.h>
  45. #include    <stdio.h>
  46. #include    <stdlib.h>
  47. #include    <string.h>
  48. #define     INCL_RXSHV
  49. #define     INCL_RXSUBCOM
  50. #include    <rexxsaa.h>
  51.  
  52.  
  53.  
  54. /*******************************************************************/
  55. /*                                                                 */
  56. /* Function prototypes follow.                                     */
  57. /*                                                                 */
  58. /*******************************************************************/
  59. RexxSubcomHandler DevInfo;
  60.  
  61. static APIRET QueryAndSet(
  62.    PRXSTRING,
  63.    PUCHAR,
  64.    ULONG,
  65.    PBOOL);
  66.  
  67. /*******************************************************************/
  68. /*                                                                 */
  69. /* Devinfo                                                         */
  70. /*                                                                 */
  71. /* This is the main function and entry point.                      */
  72. /* This is a REXX subcommand handler, sometimes called an          */
  73. /* environment.                                                    */
  74. /*                                                                 */
  75. /* A subroutine is called to check the input command against each  */
  76. /* of the allowed commands, and handle the command if it is OK.    */
  77. /* After all the commands are done, this routine returns to REXX,  */
  78. /* passing back the new value for the REXX special variable RC.    */
  79. /* This routine also sets the REXX error/failure flag.             */
  80. /*                                                                 */
  81. /* The possible exit values are as follows                         */
  82. /*   REXX RC            Error flag          Reason                 */
  83. /*   ------------------------------------------------------------- */
  84. /*   0                  RXSUBCOM_OK         success                */
  85. /*   non-zero number    RXSUBCOM_FAILURE    non-zero return from   */
  86. /*                                          DosDevConfig or        */
  87. /*                                          RexxVariablePool       */
  88. /*   COMMAND TOO LONG   RXSUBCOM_ERROR      command more than nine */
  89. /*                                          characters long        */
  90. /*   UNKNOWN COMMAND    RXSUBCOM_ERROR      command not one of the */
  91. /*                                          following values       */
  92. /*                                          (upper and lower case  */
  93. /*                                          are both OK):          */
  94. /*                                            PARALLEL             */
  95. /*                                            RS232                */
  96. /*                                            DISKETTE             */
  97. /*                                            MATH                 */
  98. /*                                            SUBMODEL             */
  99. /*                                            MODEL                */
  100. /*                                            DISPLAY              */
  101. /*                                            ALL                  */
  102. /*                                                                 */
  103. /*******************************************************************/
  104.  
  105. ULONG DevInfo(
  106.    PRXSTRING cmd,                      /* command string (input)  */
  107.    PUSHORT err_flag,                   /* ERROR/FAILURE  (output) */
  108.    PRXSTRING rv)                       /* string retcode (output) */
  109. {
  110.    APIRET rc,                          /* rc from function we call*/
  111.           maxrc,                       /* max value received in rc*/
  112.           finalrc;                     /* our 'return' value      */
  113.    BOOL FoundMatch;                    /* did we recognize command*/
  114.  
  115.    if (cmd->strlength > 9) {
  116.       *err_flag = RXSUBCOM_ERROR;      /* this is REXX ERROR cond.*/
  117.       strcpy(rv->strptr, "COMMAND TOO LONG");
  118.       rv->strlength = strlen(rv->strptr);
  119.       finalrc = 0;                     /* let string be the RC    */
  120.  
  121.    } else {
  122.       /* Now check for all possible commands, and do the          */
  123.       /* requested operation.                                     */
  124.       maxrc = 0;
  125.       FoundMatch = 0;
  126.  
  127.       rc = QueryAndSet(cmd, "PARALLEL", DEVINFO_PRINTER,
  128.          &FoundMatch);
  129.       if(rc > maxrc) maxrc = rc;
  130.  
  131.       rc = QueryAndSet(cmd, "RS232", DEVINFO_RS232,
  132.          &FoundMatch);
  133.       if(rc > maxrc) maxrc = rc;
  134.  
  135.       rc = QueryAndSet(cmd, "DISKETTE", DEVINFO_FLOPPY,
  136.          &FoundMatch);
  137.       if(rc > maxrc) maxrc = rc;
  138.  
  139.       rc = QueryAndSet(cmd, "MATH", DEVINFO_COPROCESSOR,
  140.          &FoundMatch);
  141.       if(rc > maxrc) maxrc = rc;
  142.  
  143.       rc = QueryAndSet(cmd, "SUBMODEL", DEVINFO_SUBMODEL,
  144.          &FoundMatch);
  145.       if(rc > maxrc) maxrc = rc;
  146.  
  147.       rc = QueryAndSet(cmd, "MODEL", DEVINFO_MODEL,
  148.          &FoundMatch);
  149.       if(rc > maxrc) maxrc = rc;
  150.  
  151.       rc = QueryAndSet(cmd, "DISPLAY", DEVINFO_ADAPTER,
  152.          &FoundMatch);
  153.       if(rc > maxrc) maxrc = rc;
  154.  
  155.       /* We've checked all the valid input commands and have done */
  156.       /* the processing.  Now we set up our return values and exit*/
  157.       if (!FoundMatch) {
  158.          *err_flag = RXSUBCOM_ERROR;   /* Raise ERROR in REXX pgm.*/
  159.          strcpy(rv->strptr, "UNKNOWN COMMAND");
  160.          rv->strlength = strlen(rv->strptr);
  161.          finalrc = 0;                  /* let the string be the RC*/
  162.       } else {
  163.          if (maxrc != 0) {
  164.             *err_flag = RXSUBCOM_FAILURE;/* Raise FAILURE in REXX */
  165.             finalrc = maxrc;           /* use integer as REXX RC  */
  166.          } else {
  167.             /* finally, the successful case is handled.           */
  168.             /* We return with the RXSTRING set to all zeros, and  */
  169.             /* the return value set to 0.  This makes the REXX    */
  170.             /* RC value "0".  We could also make the return value */
  171.             /* RXSTRING into the string "0", and again return 0.  */
  172.             /* That would also set the REXX RC value to "0".      */
  173.             *err_flag = RXSUBCOM_OK;
  174.             finalrc = 0;
  175.             MAKERXSTRING(*rv, (PUCHAR) 0, 0);
  176.          } /* end successful case, return code is zero            */
  177.  
  178.       } /* end Found a match                                      */
  179.  
  180.    } /* endif cmd->strlength .....                                */
  181.  
  182.    return finalrc;
  183. }
  184.  
  185. /*******************************************************************/
  186. /*                                                                 */
  187. /* QueryAndSet                                                     */
  188. /*                                                                 */
  189. /* This routine will check the data passed to it, and make at most */
  190. /* one call to DosDevConfig.  It that call is OK, it calls         */
  191. /* RexxVariablePool to put the returned data into a REXX variable. */
  192. /*                                                                 */
  193. /*******************************************************************/
  194.  
  195. static APIRET QueryAndSet(
  196.    PRXSTRING cmd,                   /* User's command              */
  197.    PUCHAR name,                     /* Command name to compare with*/
  198.    ULONG DeviceType,                /* code for DosDevConfig       */
  199.    PBOOL FoundMatch)                /* we indicate if name matches */
  200. {
  201.    SHVBLOCK block;                  /* block to pass to REXX       */
  202.    BYTE DeviceInfoByte;             /* area to hold BYTE size info */
  203.    LONG DeviceInfoDword;            /* area to hold DWORD size info*/
  204.    UCHAR ValueBuffer [12];          /* buffer to hold convered info*/
  205.    PVOID DeviceInfoPointer;         /* pointer to output area      */
  206.    APIRET rc;                       /* return code from calls      */
  207.  
  208. /* First we compare the user's command with the command name       */
  209. /* we are trying for, and ALL.  If either matches we go on and     */
  210. /* call DosDevConfig.                                              */
  211.    if (!stricmp(cmd->strptr, (const char *)name) || !stricmp(cmd->strptr, "ALL")) {
  212.       *FoundMatch = 1;                 /* record that we got match */
  213.       if (DeviceType <= 6) {
  214.          DeviceInfoPointer = (PVOID) &DeviceInfoByte;
  215.       } else {
  216.          DeviceInfoPointer = (PVOID) &DeviceInfoDword;
  217.       } /* endif */
  218.  
  219.       rc = DosDevConfig(DeviceInfoPointer, DeviceType);
  220.       if (!rc) {
  221.          /* Now turn the returned value into a string in decimal.  */
  222.          if (DeviceType <= 6) {
  223.             sprintf(ValueBuffer, "%d", (int) DeviceInfoByte);
  224.          } else {
  225.             sprintf(ValueBuffer, "%d", (int) DeviceInfoDword);
  226.          } /* endif */
  227.  
  228.          /* Build the Shared Variable Block that defines our       */
  229.          /* request.  The shvnext pointer is null because we only  */
  230.          /* are doing one request.                                 */
  231.          /* The shvname RXSTRING is the name passed to this routine*/
  232.          /* The shvvalue RXSTRING is constructed from the string   */
  233.          /* we just created above.                                 */
  234.          /* The shvnamelen and shvvaluelen duplicate the lengths   */
  235.          /* from the RXSTRINGS for simple variable-setting         */
  236.          /* operations such as we are doing here.                  */
  237.          /* The shvcode is set to RXSHV_SET, which means to set    */
  238.          /* the variable, using its name as-is.  This means the    */
  239.          /* name must be a valid REXX symbol, in upper case.       */
  240.          /* The shvret byte is not set--it is an output value.     */
  241.  
  242.          block.shvnext = (PSHVBLOCK) NULL;
  243.          block.shvname.strptr = name;
  244.          block.shvname.strlength = strlen((const char *)name);
  245.          MAKERXSTRING(block.shvvalue, ValueBuffer,
  246.                       strlen((const char *)ValueBuffer));
  247.          block.shvnamelen = block.shvname.strlength;
  248.          block.shvvaluelen = block.shvvalue.strlength;
  249.          block.shvcode = RXSHV_SET;
  250.  
  251.          /* Call the REXX variable pool.  We use an AND operation  */
  252.          /* to turn off the low-order bit in the return code,      */
  253.          /* because that bit indicates "new variable created", and */
  254.          /* we do not care about that.  Other return values        */
  255.          /* indicate an error.                                     */
  256.          rc = RexxVariablePool(&block) & 0xFFFFFFFE;
  257.  
  258.       } /* endif rc from DosDevConfig was zero                     */
  259.    }  /* End if we got a match */
  260.    else
  261.       {
  262.          rc = 0;
  263.       }  /* End we did not get a match */
  264.  
  265.    return rc; /* rc from DosDeviceConfig or RexxVariablePool, or 0 */
  266. }
  267.  
  268.