home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************/
- /* */
- /* Module Name: DEVINFO.C */
- /* */
- /* Description: Provide access to system device */
- /* device configuration information from REXX */
- /* programs. The information is obtained from */
- /* DosDevConfig. */
- /* */
- /* Function: Call DosDevConfig and store information */
- /* in the REXX program through the REXX */
- /* Variable Pool Interface (RexxVariablePool). */
- /* */
- /* Entry point: DevInfo */
- /* */
- /* Notes: */
- /* */
- /* The entry point obeys the calling conventions for REXX */
- /* subcommand handlers. */
- /* */
- /*******************************************************************/
-
- /*******************************************************************/
- /* */
- /* Include files. We use the following: */
- /* */
- /* REXXSAA.H REXX specific type definitions and */
- /* function prototypes. */
- /* */
- /* OS2.H OS/2 specific type definitions and */
- /* function prototypes. */
- /* */
- /* stdio.h Standard C library I/O function prototypes.*/
- /* */
- /* stdlib.h Standard C library function prototypes. */
- /* */
- /* string.h Standard C library string function */
- /* prototypes. */
- /* */
- /*******************************************************************/
-
-
- #define INCL_DOSDEVICES
- #include <os2.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define INCL_RXSHV
- #define INCL_RXSUBCOM
- #include <rexxsaa.h>
-
-
-
- /*******************************************************************/
- /* */
- /* Function prototypes follow. */
- /* */
- /*******************************************************************/
- RexxSubcomHandler DevInfo;
-
- static APIRET QueryAndSet(
- PRXSTRING,
- PUCHAR,
- ULONG,
- PBOOL);
-
- /*******************************************************************/
- /* */
- /* Devinfo */
- /* */
- /* This is the main function and entry point. */
- /* This is a REXX subcommand handler, sometimes called an */
- /* environment. */
- /* */
- /* A subroutine is called to check the input command against each */
- /* of the allowed commands, and handle the command if it is OK. */
- /* After all the commands are done, this routine returns to REXX, */
- /* passing back the new value for the REXX special variable RC. */
- /* This routine also sets the REXX error/failure flag. */
- /* */
- /* The possible exit values are as follows */
- /* REXX RC Error flag Reason */
- /* ------------------------------------------------------------- */
- /* 0 RXSUBCOM_OK success */
- /* non-zero number RXSUBCOM_FAILURE non-zero return from */
- /* DosDevConfig or */
- /* RexxVariablePool */
- /* COMMAND TOO LONG RXSUBCOM_ERROR command more than nine */
- /* characters long */
- /* UNKNOWN COMMAND RXSUBCOM_ERROR command not one of the */
- /* following values */
- /* (upper and lower case */
- /* are both OK): */
- /* PARALLEL */
- /* RS232 */
- /* DISKETTE */
- /* MATH */
- /* SUBMODEL */
- /* MODEL */
- /* DISPLAY */
- /* ALL */
- /* */
- /*******************************************************************/
-
- ULONG DevInfo(
- PRXSTRING cmd, /* command string (input) */
- PUSHORT err_flag, /* ERROR/FAILURE (output) */
- PRXSTRING rv) /* string retcode (output) */
- {
- APIRET rc, /* rc from function we call*/
- maxrc, /* max value received in rc*/
- finalrc; /* our 'return' value */
- BOOL FoundMatch; /* did we recognize command*/
-
- if (cmd->strlength > 9) {
- *err_flag = RXSUBCOM_ERROR; /* this is REXX ERROR cond.*/
- strcpy(rv->strptr, "COMMAND TOO LONG");
- rv->strlength = strlen(rv->strptr);
- finalrc = 0; /* let string be the RC */
-
- } else {
- /* Now check for all possible commands, and do the */
- /* requested operation. */
- maxrc = 0;
- FoundMatch = 0;
-
- rc = QueryAndSet(cmd, "PARALLEL", DEVINFO_PRINTER,
- &FoundMatch);
- if(rc > maxrc) maxrc = rc;
-
- rc = QueryAndSet(cmd, "RS232", DEVINFO_RS232,
- &FoundMatch);
- if(rc > maxrc) maxrc = rc;
-
- rc = QueryAndSet(cmd, "DISKETTE", DEVINFO_FLOPPY,
- &FoundMatch);
- if(rc > maxrc) maxrc = rc;
-
- rc = QueryAndSet(cmd, "MATH", DEVINFO_COPROCESSOR,
- &FoundMatch);
- if(rc > maxrc) maxrc = rc;
-
- rc = QueryAndSet(cmd, "SUBMODEL", DEVINFO_SUBMODEL,
- &FoundMatch);
- if(rc > maxrc) maxrc = rc;
-
- rc = QueryAndSet(cmd, "MODEL", DEVINFO_MODEL,
- &FoundMatch);
- if(rc > maxrc) maxrc = rc;
-
- rc = QueryAndSet(cmd, "DISPLAY", DEVINFO_ADAPTER,
- &FoundMatch);
- if(rc > maxrc) maxrc = rc;
-
- /* We've checked all the valid input commands and have done */
- /* the processing. Now we set up our return values and exit*/
- if (!FoundMatch) {
- *err_flag = RXSUBCOM_ERROR; /* Raise ERROR in REXX pgm.*/
- strcpy(rv->strptr, "UNKNOWN COMMAND");
- rv->strlength = strlen(rv->strptr);
- finalrc = 0; /* let the string be the RC*/
- } else {
- if (maxrc != 0) {
- *err_flag = RXSUBCOM_FAILURE;/* Raise FAILURE in REXX */
- finalrc = maxrc; /* use integer as REXX RC */
- } else {
- /* finally, the successful case is handled. */
- /* We return with the RXSTRING set to all zeros, and */
- /* the return value set to 0. This makes the REXX */
- /* RC value "0". We could also make the return value */
- /* RXSTRING into the string "0", and again return 0. */
- /* That would also set the REXX RC value to "0". */
- *err_flag = RXSUBCOM_OK;
- finalrc = 0;
- MAKERXSTRING(*rv, (PUCHAR) 0, 0);
- } /* end successful case, return code is zero */
-
- } /* end Found a match */
-
- } /* endif cmd->strlength ..... */
-
- return finalrc;
- }
-
- /*******************************************************************/
- /* */
- /* QueryAndSet */
- /* */
- /* This routine will check the data passed to it, and make at most */
- /* one call to DosDevConfig. It that call is OK, it calls */
- /* RexxVariablePool to put the returned data into a REXX variable. */
- /* */
- /*******************************************************************/
-
- static APIRET QueryAndSet(
- PRXSTRING cmd, /* User's command */
- PUCHAR name, /* Command name to compare with*/
- ULONG DeviceType, /* code for DosDevConfig */
- PBOOL FoundMatch) /* we indicate if name matches */
- {
- SHVBLOCK block; /* block to pass to REXX */
- BYTE DeviceInfoByte; /* area to hold BYTE size info */
- LONG DeviceInfoDword; /* area to hold DWORD size info*/
- UCHAR ValueBuffer [12]; /* buffer to hold convered info*/
- PVOID DeviceInfoPointer; /* pointer to output area */
- APIRET rc; /* return code from calls */
-
- /* First we compare the user's command with the command name */
- /* we are trying for, and ALL. If either matches we go on and */
- /* call DosDevConfig. */
- if (!stricmp(cmd->strptr, name) || !stricmp(cmd->strptr, "ALL")) {
- *FoundMatch = 1; /* record that we got match */
- if (DeviceType <= 6) {
- DeviceInfoPointer = (PVOID) &DeviceInfoByte;
- } else {
- DeviceInfoPointer = (PVOID) &DeviceInfoDword;
- } /* endif */
-
- rc = DosDevConfig(DeviceInfoPointer, DeviceType);
- if (!rc) {
- /* Now turn the returned value into a string in decimal. */
- if (DeviceType <= 6) {
- sprintf(ValueBuffer, "%d", (int) DeviceInfoByte);
- } else {
- sprintf(ValueBuffer, "%d", (int) DeviceInfoDword);
- } /* endif */
-
- /* Build the Shared Variable Block that defines our */
- /* request. The shvnext pointer is null because we only */
- /* are doing one request. */
- /* The shvname RXSTRING is the name passed to this routine*/
- /* The shvvalue RXSTRING is constructed from the string */
- /* we just created above. */
- /* The shvnamelen and shvvaluelen duplicate the lengths */
- /* from the RXSTRINGS for simple variable-setting */
- /* operations such as we are doing here. */
- /* The shvcode is set to RXSHV_SET, which means to set */
- /* the variable, using its name as-is. This means the */
- /* name must be a valid REXX symbol, in upper case. */
- /* The shvret byte is not set--it is an output value. */
-
- block.shvnext = (PSHVBLOCK) NULL;
- block.shvname.strptr = name;
- block.shvname.strlength = strlen(name);
- MAKERXSTRING(block.shvvalue, ValueBuffer,
- strlen(ValueBuffer));
- block.shvnamelen = block.shvname.strlength;
- block.shvvaluelen = block.shvvalue.strlength;
- block.shvcode = RXSHV_SET;
-
- /* Call the REXX variable pool. We use an AND operation */
- /* to turn off the low-order bit in the return code, */
- /* because that bit indicates "new variable created", and */
- /* we do not care about that. Other return values */
- /* indicate an error. */
- rc = RexxVariablePool(&block) & 0xFFFFFFFE;
-
- } /* endif rc from DosDevConfig was zero */
- } /* End if we got a match */
- else
- {
- rc = 0;
- } /* End we did not get a match */
-
- return rc; /* rc from DosDeviceConfig or RexxVariablePool, or 0 */
- }
-
-