Jump to content

REXX Tips & Tricks:Change the WPS with REXX

From EDM2
Revision as of 04:01, 20 December 2012 by Martini (talk | contribs) (OS2SYS.INI)

This section contains hints for using REXX to change the WPS.

WPS class hierarchy

This section contains the class tree for WARP 3 and WARP 4.

To get a list of all registered classes on your system use the function SysQueryClassList().

To get a hierarchical list of the WPS classes registered on your system you can use the Search-Button of the LaunchPad (or the entry Find ... in the WPS context menu) as follows:

  • Open the Find dialog
  • Push the More ... button in the Find dialog to open the Find Criteria dialog
  • Push the Add button in the Find Criteria dialog to open the Add Criteria dialog
  • Select Object Class for the field Attribute in the Add Criteria dialog
  • Now you can scroll the hierarchical list of the registered classes in the list box Comparison value.

In der deutschen Version von WARP oeffnet mensch hierfuer den Suchen Dialog (ueber den Suchen Button der Klickstartleiste oder ueber den Eintrag Suchen im Kontextmenue der WPS. Dort klickt mensch den Button Weitere und in den daraufhin erscheinenden Dialog den Button Hinzufuegen In diesen Dialog nun setzt mensch das Feld Merkmal auf ObjektKlasse. Nun kann in der Listbox Vergleichswert die hierarchische Liste der registrierten WPS Klassen durch gescrollt werden.

WARP Version 3 Class hierarchy

WPS Class hierarchy for WARP Version 3 (see also the WPS Class hierarchy for WARP 4).


CLASS NAME CLASS DEFINITION FILE
SOMObject somobj.idl
SOMClass somcls.idl
SOMClassMgr somcm.idl
WPObject wpobject.idl
WPAbstract wpabs.idl
WPClock wpclock.idl
WPCountry wpctry.idl
WPDisk wpdisk.idl
WPKeyboard wpkeybd.idl.idl
WPLaunchPad wplnchpd.idl
WPMouse wpmouse.idl
WPSchemePalette wppalet.idl
WPColorPalette wpclrpal.idl
WPFontPalette wpfntpal.idl
WPSchemePalette wpscheme.idl
WPPower wppower.idl
WPPrinter wpprint.idl
WPRPrinter wprprint.idl
WPProgram wppgm.idl
WPShadow wpshadow.idl
WPNetLink wpnetlnk.idl
WPShredder wpshred.idl
WPSound wpsound.idl
WPSpecialNeeds wpspneed.idl
WPSpool wpspool.idl
WPSystem wpsystem.idl
WPWinConfig wincfg.idl
WPFileSystem wpfsys.idl
WPDataFile wpdataf.idl
WPBitmap wpbitmap.idl
WebExplorer_Url
WPIcon wpicon.idl
WPMet wpmet.idl
WPPif wppif.idl
WPPointer wpptr.idl
WPProgramFile wppgmf.idl
WPCommandFile wpcmdf.idl
WPFolder wpfolder.idl
WPDesktop wpdesk.idl
WPDrives wpdrives.idl
WPMinWinViewer wpmwv.idl
WPNetgrp wpnetgrp.idl
WPNetwork wpnetwrk.idl
WPRootFolder wprootf.idl
WPServer wpserver.idl
WPSharedDir wpshdir.idl
WPStartup wpstart.idl
WPTemplates wptemps.idl
WPTransient wptrans.idl
WPJob wpjob.idl
WPPdr wppdr.idl
WPPort wpport.idl
WPQdr wpqdr.idl

(except for the classes marked with *. These are no standard WPS classes.)

WARP Version 4 Class hierarchy

WPS Class hierarchy for WARP Version 4 (see also the WPS Class hierarchy for WARP 3).


CLASS NAME                         CLASS DEFINITION FILE
SOMObject                                     somobj.idl
  ÃÄÄÄSOMClass                                somcls.idl
  ÃÄÄÄSOMClassMgr                             somcm.idl
  ³    ÀÄWPClassManager                       wpclsmgr.idl
  ÀÄÄÄWPObject                                wpobject.idl
        ÚÄÄÄÄÄWPAbstract                      wpabs.idl
        ³     ÃÄÄ WPClock                     wpclkm.idl
        ³     ÃÄÄ WPCountry                   wpctry.idl
        ³     ÃÄÄ WPDisk                      wpdisk.idl
        ³     ÃÄÄ WPLaunchPad                 wplnchpd.idl
        ³     ³     ÀÄÄSmartCenter
        ³     ÃÄÄ WPKeyboard                  wpkeybd.idl
        ³     ÃÄÄ WPMouse                     wpmouse.idl
        ³     ÃÄÄ WPPalette                   wppalet.idl
        ³     ³     ÃÄÄ WPColorPalette        wpclrpal.idl
        ³     ³     ÃÄÄ WPFontPalette         wpfntpal.idl
        ³     ³     ÀÄÄ WPSchemePalette       wpscheme.idl
        ³     ÃÄÄ WPPower                     wppower.idl
        ³     ÃÄÄ WPPrinter                   wpprint.idl
        ³     ³     ÀÄÄ WPRPrinter            wprprint.idl
        ³     ÃÄÄ WPProgram                   wppgm.idl
        ³     ÃÄÄ WPShadow                    wpshadow.idl
        ³     ³     ÀÄÄ WPNetLink             wpnetlnk.idl
        ³     ÃÄÄ WPShredder                  wpshred.idl
        ³     ÃÄÄ WPSound                     wpsound.idl
        ³     ÃÄÄ WPSpecialNeeds              wpspneed.idl
        ³     ÃÄÄ WPSpool                     wpspool.idl
        ³     ÃÄÄ WPSystem                    wpsystem.idl
        ³     ÀÄÄ WPWinConfig                 wincfg.idl
        ÃÄÄ WPFileSystem                      wpfsys.idl
        ³     ÃÄÄ WPDataFile                  wpdataf.idl
        ³     ³     ÃÄÄ WPHtml                wphtml.idl
        ³     ³     ÃÄÄ WPIcon                wpicon.idl
        ³     ³     ÃÄÄ WPImageFile           wpimage.idl
        ³     ³     ³      ÀÄÄ WPBitmap       wpbitmap.idl
        ³     ³     ÃÄÄ WPMet                 wpmet.idl
        ³     ³     ÃÄÄ WPPif                 wppif.idl
        ³     ³     ÃÄÄ WPPointer             wpptr.idl
        ³     ³     ÃÄÄ WPProgramFile         wppgmf.idl
        ³     ³     ³       ÀÄÄ WPCommandFile wpcmdf.idl
        ³     ³     ÃÄÄ WPUrl                 wpurl.idl
        ³     ÃÄÄ WPFolder                    wpfolder.idl
        ³     ³     ÃÄÄ WPDesktop             wpdesk.idl
        ³     ³     ÃÄÄ WPDrives              wpdrives.idl
        ³     ³     ÃÄÄ WPHost                 wphost.idl
        ³     ³     ÃÄÄ WPHwManager           wphwmgr.idl
        ³     ³     ÃÄÄ WPMinWinViewer        wpmwv.idl
        ³     ³     ÃÄÄ WPNetgrp              wpnetgrp.idl
        ³     ³     ÃÄÄ WPNetwork             wpnetwrk.idl
        ³     ³     ÃÄÄ WPRootFolder          wprootf.idl
        ³     ³     ÃÄÄ WPServer              wpserver.idl
        ³     ³     ÃÄÄ WPSharedDir           wpshdir.idl
        ³     ³     ÃÄÄ WPStartup             wpstart.idl
        ³     ³     ÃÄÄ WPTemplates           wptemps.idl
        ³     ³     ÀÄÄ WPUrlFolder           wpurlfdr.idl
        ÀÄÄ WPTransient                       wptrans.idl
              ÚÄÄ WPJob                       wpjob.idl
              ÃÄÄ WPDevice                    wpdevice.idl
              ³     ÃÄÄ WPDevAudio            wpaudio.idl
              ³     ÃÄÄ WPDevBus              wpbus.idl
              ³     ÃÄÄ WPDevCDRom            wpcdrom.idl
              ³     ÃÄÄ WPDevCPU              wpcpu.idl
              ³     ÃÄÄ WPDevDiskette         wpdskett.idl
              ³     ÃÄÄ WPDevDisplay          wpdisply.idl
              ³     ÃÄÄ WPDevHarddrive        wphrddrv.idl
              ³     ÃÄÄ WPDevKeyboard         wpkeybdd.idl
              ³     ÃÄÄ WPDevMemory           wpmem.idl
              ³     ÃÄÄ WPDevMouse            wpmoused.idl
              ³     ÃÄÄ WPDevParallel         wpparal.idl
              ³     ÃÄÄ WPDevPeriph           wpperiph.idl
              ³     ÃÄÄ WPDevSerial           wpserial.idl
              ³     ÃÄÄ WPDevTape             wptape.idl
              ³     ÀÄÄ WPDevTimer            wptimer.idl
              ÃÄÄ WPPort                      wpport.idl
              ÃÄÄ WPPdr                       wppdr.idl
              ÀÄÄ WPQdr                       wpqdr.idl

Note: According to the REXX Reference Summary Handbook the class SmartCenter is a sub class of WPAbstract. I have not been able to verify this.


Extended Attributes used by the WPS

The Workplace Shell uses the following extended attributes:

Extended Attribute EA Type Description
ASSOCTABLE EAT_MVMT Enables an application to indicate the type, extension, and icon for the data file that it recognizes.
.CLASSINFO EAT_BINARY the class type of the object.
.CODEPAGE the code page for the file object
.COMMENTS EAT_MVMT misc. notes or reminders about the file object
.HISTORY EAT_MVMT the modification history for a file object (see Maintaine Multi value EAs in REXX for an example for using this EA)
.ICON EAT_ICON the icon that represents the file or folder object. This EA contains the physical data used to represent the folder object. (see also Extract the icon from the EAs)
.ICON1 EAT_ICON the animation icon for a folder. This EA contains the physical data used to represent the open folder object. (see also Extract the icon from the EAs)
.ICONPOS EAT_BINARY the icon positioning information for a folder (WARP 4 only!)
.KEYPHRASES EAT_MVMT text phrases for the file
.LONGNAME EAT_ASCII the long name of the file object (necessary for file system that do not support long names) (see Copy a file from HPFS to FAT and vice versa for an usage example)
.PREVCLASS EAT_BINARY "old class name when the user requests that an object, which is a descendent of WPDataFile, becomes another subclass of WPDataFile" (WARP 4 only!)
.SUBJECT EAT_ASCII a brief summary of the content or purpose of the file object
.TYPE EAT_MVMT the file type of the file object, such as plain text (TXT), bitmap (BMP), or executable (EXE).
.VERSION EAT_ASCII or EAT_BINARY the version of the file object


See the next section for the possible EA types.

Note: "Standard Extended Attributes (SEAs) have a dot (.) as a prefix. This identifies the extended attribute as a SEA. The leading dot is reserved, so applications should not define extended attributes that start with a dot. Also, extended attributes that start with the characters $, @, &, or + are reserved for system use."

Be aware that the information about the types of the Standard Extended Attributes in the Control Program Guide and Reference is not correct!

Extended Attribute Data Types

The first WORD of an EA specifies the type of the EA. The following EA types are defined (see Maintaining Multi-Value EAs in REXX for example REXX code to handle EAs):

Data Type Value
EAT_ASCII 'FFFD'x

Description: This EA contains ASCII text. The first WORD following the data type specifies the length of the data; the next bytes are the data.

Example: EAT_ASCII '0005'x 'Hello'


Data Type Value
EAT_BINARY 'FFFE'x

Description: This EA contains binary (non-text) data. The first WORD following the data type specifies the length of the data; the next bytes are the data.

Example: EAT_BINARY '0003'x '01'x '02'x '03'x

Data Type Value
EAT_BITMAP 'FFFB'x

Description: This EA contains bit map data. The first WORD following the data type specifies the length of the data; the next bytes are the data.

Example: EAT_BITMAP '0203'x bitmap_data

Data Type Value
EAT_METAFILE 'FFFA'x

Description: This EA contains metafile data. The first WORD following the data type specifies the length of the data; the next bytes are the data.

Example: EAT_METAFILE '0203'x metaFile_data


Data Type Value
EAT_ICON 'FFF9'x

Description: This EA contains icon data. The first WORD following the data type specifies the length of the data; the next bytes are the data.

Example: EAT_ICON '1BF8'x icon_data

Data Type Value
EAT_EA 'FFEE'x

Description: This EA contains the ASCII name of another EA that is associated with the file. The contents of that EA are to be included in the current EA. The first WORD following the data type specifies the length of the name of the other EA; the next bytes are the name of the EA to include.

Example: EAT_EA '0008'x AB.STUFF

Data Type Value
EAT_MVMT 'FFDF'x

Description: This EA contains multi-valued, multi-typed data -- two or more consecutive extended attribute values. Each value has an explicitly specified type. The first WORD following the data type specifies the codepage (0000 means default); the second WORD following the data type specifies the number of the following entries. The next bytes specify the EA values in the "normal" EA format (see the description for the other entries). Note that the Code page data is for use by the application; the operating system does not use it.

Example: EA_MVMT '0000'x '0003'x EAT_ASCII '0005'x Hello

EAT_EA '0008'x AB.STUFF

EAT_BINARY '0003'x '01'x '02'x '03'x

Data Type Value
EAT_MVST FFDE'x

Description: This EA contains multi-valued, single-typed data-two or more consecutive extended attribute values. All values have the same type. The first WORD following the data type specifies the codepage (0000 means default); the second WORD following the data type specifies the number of the following entries. The next word specifies the data type of the values and after that the data of the values follow.

Example: EAT_MVST 0000 0003 EAT_ASCII 0004 Mark

0005 Ellen

0003 Liz

Data Type Value
EAT_ASN1 'FFDD'x

Description: This EA contains ANS.1 field data; an ISO standard for describing multivalue data streams.

Data Type Value
'8000'x and up

Description: These values are reserved for the Operating System.


Data Type Value
'0000'x - '7FFF'x


Description: These values can be defined by the user. All user-defined data types should be length-preceded, meaning that a WORD indicating the length of the data (in bytes) precedes the data.

Source: Control Program Guide and Reference

Force the WPS to reRead the Extended Attributes

To force the WPS to reread the Extended Attributes (for example after changing the EA .LONGNAME) of a file you can use the following code (Source: Found in a public newsgroup):

/*   */
  CALL RxFuncAdd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'
  CALL SysLoadFuncs

                    /* create a temporary file in the TEMP directory  */
  tempDir = value( 'TEMP',, 'OS2ENVIRONMENT' )
  tempFile = time('S')

  if right( tempDir,1 ) = '\' then
    tempFile = tempDir || tempFile
  else
    tempFile = tempDir || '\' || tempFile

                    /* now open the folder on the WPS                 */
  call SysSetObjectData tempDir, 'OPEN=DEFAULT;'

  say 'Creating a file named "' || tempFile || '" ...'

                    /* create a temporary file                        */
  '@ECHO. This is a test file ' '>'tempFile
  say ' ... done'

  say 'Press any key after the file is shown in the folder ...'
  '@pause >NUL'

                    /* new value for the EA .LONGNAME                 */
  NewLongName = 'This is a very looong Name' || '00'x

                    /* create a valid EA                              */
  typeinfo = 'FDFF'x || d2c(length(NewLongName)) || '00'x || NewLongName

  say 'Now changing the EA .LONGNAME of the file to'
  say ' "' || newLongName ||  '" ...'
  say '(This should change the title used in the WPS!)'

                   /* change the EA                                   */
  call SysPutEA tempFile, ".LONGNAME", typeinfo
  say ' ... done'
  say
  say 'Press any key to force the WPS to reRead the EAs'
  say '(and update the title in the folder) ...'
  '@pause >NUL'

                   /* force the WPS to reread the EAs                 */
  '@attrib -a ' tempFile '2>NUL 1>NUL'
  '@attrib +a ' tempFile '2>NUL 1>NUL'

  say 'Now the WPS should show the new title for the object.'

  say 'Press any key to delete the temporary file ...'
  '@pause >NUL'

                    /* delete the temporary file                      */
  '@DEL ' tempFile '2>NUL 1>NUL'
exit 0
 

Format of the RC files for MAKEINI

A detailed description of the format of the RC files used by MAKEINI is included in the book OS/2 2.11 Power Techniques. (see also Predefined Object IDs)

Note: see Get the default object settings for an example for parsing an RC file.

Note: In OS/2 WARP, the UPDATE and REPLACE flags in the setup strings of some of the entries in the INI.RC have no effect on the options in the object's pop-up menu of existing objects. To get around this limitation, use �SysSetObjectData to change the object properties (Source: APAR PJ18673).

Contents of the OS/2 INI files

OS/2 saves a big part of its configuration in the files OS2.INI and OS2SYS.INI. Therefore, many of the changes you might make to the WPS with REXX will involve changing some entries in these INI files.

The basic structure of OS/2 INI files is hierarchical, consisting of the following elements and order:


 Application
             Key
                 Value

Applications are the main entries. Each application must have at least one Key, and each Key must have a Value (Note that a lot of Values - but not all - include a trailing NULL byte ['00'x]). This byte may be needed for certain values to function properly. It should not be discarded when values are modified.)

To read or change INI file entries in REXX programs you can use the REXXUTIL function �SysIni. For example, to read the value of the key PDR_DIR of the application PM_INSTALL in the file OS2.INI you can use the REXX statement


  pdr_dir = SysIni( 'USER', 'PM_INSTALL', 'PDR_DIR' )
  if pdr_dir = 'ERROR:' then
     say 'Error reading the key from the INI file!'

To change the value of this key you can use


  newPDR_DIR = 'I:\OS2IMAGE' || '00'x
  thisRC = SysIni( 'USER', 'PM_INSTALL', 'PDR_DIR', newPDR_DIR )
  if thisRC = 'ERROR:' then
     say 'Error reading the key from the INI file!'

(BTW: The key used in the example above holds the name of the directory with the OS/2 image files (I:\OS2IMAGE) from which the system was installed. The value of this key is also the default value for the directory containing the OS/2 image if you do a Selective Install. The drive letter represents the drive that was used when the system was installed; therefore it can differ from one installation to another)

A detailed description of the contents of the OS/2 INI files (including many REXX samples to change the entries) is included in the book OS/2 2.11 Power Techniques. (Don't mind the version 2.11 in the title - the book is also useful for WARP 4).

Some useful entries are described in the next sections.

Note that, unless noted otherwise, all entries below have been tested only with OS/2 WARP Version 3.

You can use the program ConvIni.CMD to convert parts or all of an INI file into a REXX program to recreate the INI file entries.

Sample INI file entries

Following is a list of some useful entries in the OS/2 INI files. Warning:

Be aware that these entries are not documented by IBM! They may change in different releases of OS/2 without notice! (see Changing the Lockup page entries for an example)

Use this information with extreme care! Improper use could lead to unpredictable behavior of the system, possibly including problems booting and starting the WPS. Further Warning:

The names (!) of some keys in the INI files are language dependent! (see Font Size for text (VIO) windows for an example)!


OS2.INI

Country dependent information

File OS2.INI

Application PM_National

Key (various, see below)

Value

Description This application contains the country-dependent information

Created -

Deleted -

Possible keys for this application (copied from the file \OS2\INI.RC. ):


 "iCountry"      "1"   /* Country code (phone ID of country)         */
 "iDate"         "0"   /* Date mode (0:MDY, 1:DMY, 2:YMD)            */
 "iCurrency"     "0"   /* Currency mode 0: prefix, no sep            */
                       /*    1: suffix, no separation                */
                       /*    2: prefix, 1 CHAR separation            */
                       /*    3: suffix, 1 CHAR separation            */
 "iDigits"       "2"   /* Signif Decimal digits in Currency          */
 "iTime"         "0"   /* time mode (0=12 hours clock, 1=24)         */
 "iLzero"        "0"   /* Leading zeros (0: no, 1: yes)              */
 "s1159"         "AM"  /* Trailing string 0:00 to 11:59              */
 "s2359"         "PM"  /* Trailing string 12:00 to 23:59             */
 "sCurrency"     "$"   /* Currency Symbol string                     */
 "sThousand"     ","   /* Thousands separator string                 */
 "sDecimal"      "."   /* Decimal separator string                   */
 "sDate"         "-"   /* Date separator string                      */
 "sTime"         ":"   /* time separator string                      */
 "sList"         ","   /* List separator string.                     */
 "iMeasurement"  "1"   /* 1=English, 2=Metric, 3=Points, 4=Picaa     */
Font size for text (VIO) windows

File OS2.INI

Application Shield

Key ~Font Size...

Value "ccrr"x

cc = number of cols

rr = number of rows (hexadecimal values)

Description contains the default font size for new text windows

Created After pressing the Save button in the font dialog of a text window

Deleted ?

Example Use "080E"x for the font size 14*8

The value of this key is only used for new text windows. To open a window with a specific size you may

  • save the current value of the key
  • set the key to the needed value
  • open the text window
  • and restore the value of the key

see Start a VIO session with a specific font size for an example)

Warning: The name of this key is language dependent! For example in German OS/2 versions, the name of this key is Schrif~tartgröße...; in Spanish OS/2 versions, it's Tamaqo del ~font...! (The name seems to be equal to the menu entry for the popup menu.)

==Start a VIO session with a specific font size==
/*                                                                    */
/* Sample program to start an OS/2 session or a DOS box with a        */
/* specific font size                                                 */
/*                                                                    */
/* Usage:                                                             */
/*                                                                    */
/*   StartVio {fontSize} {prog_parameter}                             */
/*                                                                    */
/* where:                                                             */
/*                                                                    */
/*   fontSize                                                         */
/*                                                                    */
/*     Font for the window in the format 'HHxWW'                      */
/*     where HH = font height as decimal value                        */
/*     and   WW = font width as decimal value                         */
/*     (def.: Use default font size)                                  */
/*                                                                    */
/*   prog_parameter                                                   */
/*                                                                    */
/*     Further parameter for the START command                        */
/*     (e.g /DOS to start a DOS box)                                  */
/*                                                                    */
/*                                                                    */
/*                                                                    */
/* Example:                                                           */
/*                                                                    */
/*   Start an OS/2 Session with a 14x8 Font                           */
/*                                                                    */
/*      StartVIO 14x8                                                 */
/*                                                                    */
/*   Start a DOS Box with a 10x6 Font                                 */
/*                                                                    */
/*      StartVIO 14x8 /DOS                                            */
/*                                                                    */
/*                                                                    */
/* History                                                            */
/*   10.07.1997 v1.00 /bs                                             */
/*     - initial release (for RXT&T v2.60)                            */
/*                                                                    */
/*                                                                    */
/* Note:                                                              */
/*   Change the value for the variable "FontMenuEntry" if you're not  */
/*   using a non-english version of OS/2!                             */
/*                                                                    */
/*                                                                    */
/* (c) 1996 Bernd Schemmer, Germany, EMail: Bernd.Schemmer@gmx.de     */
/*                                                                    */

        /*  Warning:  The name of this key is language                */
        /*            dependent! For example in German OS/2           */
        /*            versions, the name of this key is               */
        /*            Schrif~tartgröße...; in Spanish OS/2            */
        /*            version, it's Tamaqo del ~font...! (The         */
        /*            name seems to be equal to the menu entry        */
        /*            for the popup menu.)                            */
        /* (see Font size for text (VIO) windows)                     */

  FontMenuEntry = '~Font Size...'

                    /* process the parameter                          */
  parse arg thisArgs

  parse var thisArgs thisFont furtherArgs

  NewFontSize = ''
  OldFontSize = ''

  if thisFont <> '' then
  do
    parse var thisFont height 'x' width

    if datatype( height ) <> 'NUM' | datatype( width ) <> 'NUM' then
    do
      furtherArgs = thisArgs
    end /* if datatype( height ) <> 'NUM'  ... */
    else
    do
      NewFontSize = d2c( width ) || d2c( height )
    end /* else */

  end /* if thisFont <> '' then */

         /* load the necessary REXXUTIL function                      */
  if newFontSize <> '' then
  do
    call rxFuncAdd 'SysIni', 'REXXUTIL', 'SysIni'

         /* save the old font size                                    */
    oldFontSize =  SysIni( 'USER', 'Shield', FontMenuEntry )

    if oldFontSize = 'ERROR:' then
      oldFontSize = ''

         /* set the new font size                                     */
    call SysIni 'USER', 'Shield', FontMenuEntry, newFontSize

  end /* if newFontSize <> '' then */

         /* start a new OS/2 session or DOS window                    */
  '@start /win' furtherArgs


         /* restore the old font size or delete the font size entry   */
         /* if no font size entry was set                             */
  if newFontSize <> '' then
  do
    if oldFontSize <> '' then
      call SysIni 'USER', 'Shield', FontMenuEntry, oldFontSize
    else
      call SysIni 'USER', 'Shield', FontMenuEntry, 'DELETE:'
  end /* if newFontSize <> '' then */

exit
Open text windows in a maximized stated

File OS2.INI

Application Shield

Key fMaximize

Value "0100"x (on)

"0000"x (off)

Description Open text windows maximized

if on

Created ?

Deleted ?

The value of this key is only used for new text windows. To open a window maximized you may

  • save the current value of the key
  • set the key to "0100"x
  • open the text window
  • and restore the value of the key.
Changing the "Save Desktop Settings" page entry

File OS2.INI

Application PM_Workplace

Key PreserveDTSettings

Value "01000000"x (on)

"00000000"x (off)

Description save the desktop at

shutdown if on

Created ?

Deleted ?

This entry represents the check box "Save Desktop Settings" on the "Desktop" page of the WPS context menu.

Changing the default font

File OS2.INI

Application PM_SystemFonts

Key DefaultFont

Value font name "00"x

Description Default font for the WPS

Created manuell

Deleted manuell

You can use this entry to change the default font for the WPS. Example:

 
/* REXX cmd to set the default font for the WPS                       */
/*                                                                    */
/* note: WarpSans is the new default font of WARP 4 (Merlin). To use  */
/*       this font in WARP 3, copy the file DSPRES.DLL from WARP 4    */
/*       to \OS2\DLL and reboot.                                      */
/*       Be careful, though! Some video drivers require a specific    */
/*       version of DSPRES.DLL to work properly.                      */
/*       If the DLL is locked (i.e., in use), just unlock it with the */
/*       Unlock program from LX lite.                                 */
/*                                                                    */

  call rxFuncAdd "SysIni", "REXXUTIL", "SysIni"

  call SysIni "USER", "PM_SystemFonts", "DefaultFont",,
            "9.WarpSans" || "00"x
Get the display resolution

File OS2.INI

Application PM_DISPLAYDRIVERS

Key DEFAULTSYSTEMRESOLUTION

Value "xxxxyyyydddd????????"x

xxxx = horizontal resolution

yyyy = vertical resolution

dddd = color depth

???? = unknown value

(all values in LSB format)

Description contains the current display resolution

Created ?

Deleted ?

File OS2.INI

Application PM_DISPLAYDRIVERS

Key RESOLUTION_CHANGED

Value "3100"x

Description display resolution change is pending if this key exists

Created after changing the current resolution using the System object

Deleted after the next reboot

Following is an example program using the known values of these entries to get the current display resolution.

/* ------------------------------------------------------------------ */
/* sample program to get the current display resolution               */
/*                                                                    */

                    /* load the necessary REXXUTIL function           */
  call rxFuncAdd "SysIni", "REXXUTIL", "SysIni"

                    /* get the resolution                             */
  parse value GetDisplayResolution() with ,
        xResolution yResolution ColorDepth resolutionChangePending

                    /* display the results                            */
  say "Your current display resolution is " || ,
      XResolution || "x" || YResolution || "x" || ColorDepth

                    /* check if the resolution is already valid       */
  if resolutionChangePending = 1 then
  do
    say ""
    say "Note: You've changed the resolution but not rebooted until now."
    say "      So maybe the resolution mentioned above is only valid after"
    say "      the next reboot!"
  end /* if */

exit 0

/* ------------------------------------------------------------------ */
/* function: Get the current display resolution                       */
/*                                                                    */
/* call:     GetDisplayResolution                                     */
/*                                                                    */
/* returns:  xValue yValue depth changePending                        */
/*                                                                    */
/* where:    xValue - horizontal size                                 */
/*           yValue - vertical size                                   */
/*           depth  - colorDepth                                      */
/*           changePending - 1 : the resolution was changed but no    */
/*                               reboot occurred until now            */
/*                           0 : the resolution is active             */
/*                                                                    */
/* note:     unknown1 and unknown2 are unknown values in the INI file */
/*           entry (see below).                                       */
/*           This routine needs the REXXUTIL function SYSINI and the  */
/*           subroutine LSB2MSB                                       */
/*                                                                    */
GetDisplayResolution: PROCEDURE

                    /* init the return code                           */
  parse value 0 0 0 0 with xValue yValue colorDepth changePending

                    /* install a local error handler                  */
  signal on syntax name GetDisplayValueError
                                   /* get the current resolution      */
  resolutionEntryInBin = SysIni( "USER" ,,
                                 "PM_DISPLAYDRIVERS" ,,
                                 "DEFAULTSYSTEMRESOLUTION" )

                    /* check, if a resolution change is pending       */
  resolutionChangePending = SysIni( "USER" ,,
                                    "PM_DISPLAYDRIVERS" ,,
                                    "RESOLUTION_CHANGED" )
   if resolutionChangePending = "1" || "00"x then
     resolutionChangePending = 1
   else
     resolutionChangePending = 0

                    /* convert the value into a hex string            */
  resolutionEntryInHex = c2x( resolutionEntryInBin )

  parse var resolutionEntryInHex  1 xValue  ,
                                  9 yValue  ,
                                 17 ColorDepth ,
                                 25 unknown1 ,
                                 33 unknown2

                    /* convert the values into decimal values         */
  xValue     = x2d( LSB2MSB( xValue ) )
  yValue     = x2d( LSB2MSB( yValue ) )
  ColorDepth = x2d( LSB2MSB( ColorDepth ) )

                    /* not returned or used in this version           */
  unknown1   = x2d( LSB2MSB( unknown1 ) )
  unknown2   = x2d( LSB2MSB( unknown2 ) )

                    /* this label is only used by the local error     */
                    /* handler                                        */
GetDisplayValueError:
  return xValue yValue colorDepth resolutionChangePending

/* ------------------------------------------------------------------ */
/* function: Convert a WORD or DWORD from LSB format to MSB format    */
/*           and vice versa                                           */
/*                                                                    */
/* call:     LSB2MSB inputHexString                                   */
/*                                                                    */
/* where:    inputHexstring - input value as hexstring                */
/*                            (e.g. "3412", "78563412")               */
/*                                                                    */
/* output:   value in MSB format as hexstring                         */
/*           (e.g. "1234", "12345678")                                */
/*                                                                    */
LSB2MSB: PROCEDURE
  HexZiffer = arg(1)                                         /* v3.00 */
  Len = Length(HexZiffer)                                    /* v3.00 */
  If (Len // 2) then                                         /* v3.00 */
     HexZiffer = Right(HexZiffer, Len + 1, '0')              /* v3.00 */
  RETURN strip( translate( "12345678",,                      /* v3.00 */
                           HexZiffer, "78563412" ) )         /* v3.00 */
List all WPS known object IDs

File OS2.INI

Application PM_Workplace:Location

Keys {known object ids}

Value ?

Description This application contains the object IDs of all known objects

Created ?

Deleted ?

You can use this application to get a list of all known object IDs (see also GETOBJ and List all objects):

/* Sample code to display all object ids known to the WPS.            */
/* Captured from a message in a public CompuServe Forum               */
/*                                                                    */

                    /* load the necessary REXXUTIL function           */
  call rxFuncAdd "SysIni", "REXXUTIL", "SysIni"

                    /* get the list of the known object IDs           */
  call SysIni "USER", "PM_Workplace:Location", "All:", "ids."

                    /* and print them to the screen                   */
  say ids.0 || " known object IDs found."
  j = 1
  do i = 1 to ids.0
    j = j + 1
    say ids.i
    if j = 23 then
    do
      say "Press RETURN to continue"
      parse pull
      j = 1
    end /* if j = 23 then */
  end /* do i = 1 to ids.0 */
exit
Icons saved in the file OS2.INI

File OS2.INI

Application PM_Abstract:Icons

Keys {object handles}

Value icon data

Description The keys of this application contain the icons for the objects

Created ?

Deleted ?

See Get icons from the OS2.INI file for an example of using this application. (see also List all objects)

List all objects

File OS2.INI

Application PM_Abstract:Objects

Keys {object handles}

Value ?

Description This application contains the handles of all known objects

Created ?

Deleted ?

You can use the DLL WPTOOLS.DLL to create a list of all known objects using this application (see also List all WPS known object IDs and GETOBJ):

Note: This program needs the routines from the section General routines for the samples!

   
    /*                                                                    */
    /* Sample program to display a list of all known objects              */
    /*                                                                    */
    /* Usage: ShowObj {>logfile}                                          */
    /*                                                                    */
    /* Note:  This program needs Henk Kelders excellent DLL WPTOOLS.DLL!  */
    /*                                                                    */
    /*        Tested under OS/2 WARP Connect. May not work on other OS/2  */
    /*        versions!                                                   */
    /*                                                                    */
    /* History                                                            */
    /*   14.01.1996 v1.00 /bs                                             */
    /*     - initial release (for RXT&T v2.00)                            */
    /*                                                                    */
    /* (c) 1996 Bernd Schemmer, Germany, EMail: Bernd.Schemmer@gmx.de     */
    /*                                                                    */

                        /* turn on the NOVALUE condition                  */
      signal on NOVALUE

                        /*  load WPTOOLS functions                        */
      call RxFuncAdd "WPToolsLoadFuncs", "WPTOOLS", "WPToolsLoadFuncs"
      call WPToolsLoadFuncs

                        /*  load REXXUTIL functions                       */
      call rxFuncAdd "SysLoadFuncs", "REXXUTIL", "SysLoadFuncs"
      call SysLoadFuncs

                        /* get all object handles                         */
      thisRC = SysIni( "USER", "PM_Abstract:Objects", "ALL:", "handleList" )


      call lineOut , "Object list"
      call LineOut , "==========="
      call LineOut , ""

                        /* display the object data                        */
      do i = 1 to handleList.0
        curHandle = handleList.i

        call CharOut , "  " || curHandle || ": "

        cur2Indent = length( curHandle ) + 4 +2
        curIndent = 0

                        /* show the data of the object                    */
        call ShowObjectData "#2" || right( "0000" || curHandle, 4 ) ,,
                            cur2Indent, curIndent

        call LineOut , ""

      end /* do i = 1 to handleList.0 */

    exit

    /* ------------- insert the routines from the section ------------- */
    /*                 General routines for the samples                 */
    /* ---------------------------- here! ----------------------------- */


List all associations

File OS2.INI

Application PMWP_ASSOC_TYPE

Keys {association types}

(e.g. "Plain Text")

Value "00"x (no association)

or a list of object

handles separated with

zero bytes ("00"x)

Description This application contains all known associations by type

Created ?

Deleted ?

File OS2.INI

Application PMWP_ASSOC_FILTER

Keys {association filters} (e.g. "*.CMD")

Value "00"x (no association) or a list of object handles separated with zero bytes ("00"x)

Description This application contains all known associations by filter

Created ?

Deleted ?

You can use the keys of these applications to get the known associations and the data of the associated objects.

Note: This program needs the routines from the section General routines for the samples!

     
    /*                                                                    */
    /* Sample program to display a list of the associations               */
    /*                                                                    */
    /* Usage: ShowAsso {>logfile}                                         */
    /*                                                                    */
    /*                                                                    */
    /* Note:  This program needs Henk Kelders excellent DLL WPTOOLS.DLL!  */
    /*                                                                    */
    /*        Tested under OS/2 WARP Connect. May not work under other    */
    /*        OS/2 versions!                                              */
    /*                                                                    */
    /* History                                                            */
    /*   14.01.1996 v1.00 /bs                                             */
    /*     - initial release (for RXT&T v2.00)                            */
    /*                                                                    */
    /* (c) 1996 Bernd Schemmer, Germany, EMail: Bernd.Schemmer@gmx.de     */
    /*                                                                    */

                        /* turn on the NOVALUE condition                  */
      signal on NOVALUE

                        /*  load REXXUTIL functions                       */
      call rxFuncAdd "SysLoadFuncs", "REXXUTIL", "SysLoadFuncs"
      call SysLoadFuncs

                        /* get all filter associations                    */
      thisRC = SysIni( "USER", "PMWP_ASSOC_FILTER", "ALL:", "assoc_filter" )

                        /* get all type associations                      */
      thisRC = SysIni( "USER", "PMWP_ASSOC_TYPE", "ALL:", "assoc_type" )


      call lineOut , "Associations by filter"
      call LineOut , "======================"
      call LineOut , ""

                        /* display filter associations                    */
      do i = 1 to assoc_filter.0
        curFilter = assoc_filter.i
        curHandle = SysIni( "USER", "PMWP_ASSOC_FILTER", curFilter )

        select

          when curHandle = "ERROR:" then
            call lineOut , "  " || curFilter || ,
                           ": Error retrieving the value for this key!"

          when curHandle = "00"x then
            call lineOut , "  " || curFilter || ,
                           ": No association for this filter."

          otherwise
          do
            call CharOut , "  " || curFilter || ": "

            cur2Indent = length( curFilter ) + 4 +2
            curIndent = 0

                        /* show the data of the associated objects        */
            do until curHandle = ""

                        /* handle multiple associations                   */
              parse var curHandle curSubHandle "00"x curHandle
              call ShowObjectData "#" || d2x( curSubHandle ) ,,
                                  cur2Indent, curIndent
              curIndent = cur2Indent -2
            end /* until curHandle = "" */

          end /* otherwise */

        end /* select */
        call LineOut , ""

      end /* do i = 1 to assoc_filter.0 */

      call lineOut , "Associations by type"
      call LineOut , "===================="
      call LineOut , ""

                        /* display filter associations                    */
      do i = 1 to assoc_type.0
        curType = assoc_type.i
        curHandle = SysIni( "USER", "PMWP_ASSOC_TYPE", curType )

        select

          when curHandle = "ERROR:" then
            call lineOut , "  " || curType || ,
                           ": Error retrieving the value for this key!"

          when curHandle = "00"x then
            call lineOut , "  " || curType || ,
                           ": No association for this type."

          otherwise
          do
            call CharOut , "  " || curType || ": "

            cur2Indent = length( curType ) + 4 +2
            curIndent = 0

                        /* show the data of the associated objects        */
            do until curHandle = ""
                        /* handle multiple associations                   */
              parse var curHandle curSubHandle "00"x curHandle
              call ShowObjectData "#" || d2x( curSubHandle ) ,,
                                  cur2Indent, curIndent
              curIndent = cur2Indent -2
            end /* until curHandle = "" */

          end /* otherwise */

        end /* select */
        call LineOut , ""

      end /* do i = 1 to assoc_type.0 */

    exit

    /* ------------- insert the routines from the section ------------- */
    /*                 General routines for the samples                 */
    /* ---------------------------- here! ----------------------------- */
Get the desktop directory
/* captured from a message in a public CompuServe forum               */
/*                                                                    */
/* Note: Seems not to work in OS/2 WARP 4!                            */
/*                                                                    */

/**********************************************************************/
/*                                                                    */
/* GETDESK.CMD                                                        */
/*                                                                    */
/* Version: 1.2                                                       */
/*                                                                    */
/* Written by: Georg Haschek (see EMail Addresses)                    */
/*                                                                    */
/* Description: Return the desktop's directory name to the caller.    */
/*                                                                    */
/* Note: If the debug parameter ("/D") is set, the output goes to the */
/*       terminal.                                                    */
/*                                                                    */
/**********************************************************************/

/**************/
/* Initialize */
/**************/

  Parse Upper Arg argstring
  debug = 0
  If Wordpos( "/D",argstring ) > 0 Then
    debug = 1

  If RxFuncQuery( "SysLoadFuncs" ) Then
  Do
    Call RxFuncAdd "SysLoadFuncs", "REXXUTIL", "SysLoadFuncs"
    Call SysLoadFuncs
  End

  If debug = 0 Then
    Return Getpath( Substr( SysIni( "USER",,
                   "PM_Workplace:Location", "<WP_DESKTOP>" ),1,2 ) )

  Call Charout ,"Your desktop directory is: "
  Say Getpath( Substr( SysIni( "USER", "PM_Workplace:Location",,
               "<WP_DESKTOP>" ),1,2 ) )
Exit 0

/***********************************************/
/* Loop through the nodes to get the path info */
/***********************************************/
Getpath: Procedure Expose nodes.
  If Getnodes( ) <> 0 Then
    Return ""

  gpinode = Arg( 1 )

  If nodes.gpinode = "" Then
    Return ""

  gp = Substr( nodes.gpinode,33,Length( nodes.gpinode )-33 )
  gpparent = Substr( nodes.gpinode,9,2 )

  If gpparent <> "0000"x Then
  Do
    Do Until gpparent = "0000"x
      gp = Substr( nodes.gpparent,33,Length( nodes.gpparent )-33 ) || ,
           "\" || gp
      gpparent = Substr( nodes.gpparent,9,2 )
    End
  End
Return gp

/*****************/
/* Get the nodes */
/*****************/
Getnodes: Procedure Expose nodes.
  handlesapp = SysIni( "SYSTEM","PM_Workplace:ActiveHandles",,
                       "HandlesAppName" )

  If handlesapp = "ERROR:" Then
    handlesapp = "PM_Workplace:Handles"

  block1 = ""
  Do i = 1 to 999
    block = SysIni( "SYSTEM", handlesapp, "BLOCK" || i )
    If block = "ERROR:" Then
    Do
      If i = 1 Then
      Do
        Say "Unable to locate the NODE table, you are probably",
            "using OS/2 2.0 without the Service Pack."
        Return 1
      End
      Leave
    End
    block1 = block1 || block
  End

  l = 0
  nodes. = ""
  Do Until l >= Length( block1 )
    If Substr( block1,l+5,4 ) = "DRIV" Then
    Do
      xl = Pos( "00"x || "NODE" || "01"x, block1,l+5 )-l
      If xl <= 0 Then
        Leave
      l = l + xl
      Iterate
    End
    Else
    Do
      If Substr( block1,l+1,4 ) = "DRIV" Then
      Do
        xl = Pos( "00"x || "NODE" || "01"x, block1,l+1 )-l
        If xl <= 0 Then
          Leave
        l = l + xl
        Iterate
      End
      Else
      Do
        data = Substr( block1,l+1,32 )
        xl = C2D( Substr( block1,l+31,1 ) )
        If xl <= 0 Then
          Leave
        data = data || Substr( block1,l+33,xl+1 )
        l = l + Length( data )
      End
    End
    xnode = Substr( data,7,2 )
    nodes.xnode = data
  End
Return 0
Get a list of all printers

(see also Add new LPT Ports)

/* captured from a message in a public IBM forum                      */

/**********************************************************************/
/*                                                                    */
/* List all printers                                                  */
/*                                                                    */
/* Written by: Georg Haschek (see EMail Addresses)                    */
/*                                                                    */
/* Description: Print a list of all printers to the display           */
/*                                                                    */
/**********************************************************************/

  if RxFuncQuery( "SysLoadFuncs" ) then
  do
    Call RxFuncAdd "SysLoadFuncs", "REXXUTIL", "SysLoadFuncs"
    Call SysLoadFuncs
  end /* if rxFuncQuery( ... */

  call SysIni "BOTH", "PM_SPOOLER_PRINTER", "ALL:", "printers"
  parse value SysIni( "BOTH", "PM_SPOOLER" , "PRINTER" ) with default ";" .

  default = strip( default )
  maxlen = 8

  do i = 1 to printers.0
    val = printers.i
    parse value SysIni( "BOTH", "PM_SPOOLER_PRINTER_DESCR", val ) ,
                          With printerd.val ";" .
    printerd.val = space( translate( printerd.val,"  ","0d0a"x ) )
    if val == default then
      printerd.val = printerd.val "[default]"
    maxlen = max( maxlen ,length( printerd.val ) )
  end /* do i = 1 to printers.0 */

  title =  "Name"||Copies( " ",maxlen-4 ) "Port     Queue    Printer driver"
  say title
  say copies( "-", length( title ) )

  do i = 1 to printers.0
    val = printers.i
    parse value SysIni( "BOTH", "PM_SPOOLER_PRINTER", val ) ,
                          With port ";" driver ";" Queue ";" .
    say left( printerd.val,maxlen ) left( strip( port ),8 ) ,
        left( strip( queue ),8) strip( driver )
  end /* do i = 1 to printers.0 */

exit 0
Changing the Lockup page entry

You cannot change the Lockup page entry using �SysSetObjectData in WARP 3. The book OS/2 2.11 Power Techniques contains some information about changing the lockup feature using the INI file entry (Partial/Full Screen Lockup, Setting Automatic Lockup and the Timeout Value, Auto Dim/No AutoDim, Reset the password, change the lockup bitmap, change the lockup bitmap display options).

In WARP 4 you can change some of the Lockup page entries and activate the Lockup using �SysSetObjectData (see Setup strings for WPDesktop objects and also Activating Lockup now)

Another method to init the lockup page entries with default values (useful for setting default values, but see also Set or get the WPS lockup password ):

Change the lockup page entries of an installed OS/2 system to meet your needs. Then call the REXX program below to create a REXX cmd to copy the lockup options to another machine:

/*                                                                    */
/* sample program to create a CMD to copy the lockup options of this  */
/* machine to other machines.                                         */
/*                                                                    */
/* This program creates a program called "SETLKUP.CMD" in the         */
/* current directory. Execute this program on other machines to copy  */
/* the lockup options of this machine.                                */
/*                                                                    */
/* Note that this program only works on OS/2 WARP. To work under      */
/* OS/2 versions prior to WARP you must change the application name   */
/* PM_Lockup to 'Lock Up Workplace' (with the blanks but without the  */
/* quotes) and the key name LockupOptions to 'Lockup_options3' (also  */
/* without the quotes).                                               */
/*                                                                    */
/* To use the program under 2.11 and WARP you may use the REXXUTIL    */
/* function �SysOS2Ver to distinguish between the versions --         */
/* but please note that I did NOT test if it is possible to use the   */
/* same values for different OS/2 versions!                           */
/*                                                                    */
/* (c) 1996 Bernd Schemmer, Germany, EMail: Bernd.Schemmer@gmx.de     */
/*                                                                    */

                    /* load the necessary REXXUTIL function(s)        */
  call rxFuncAdd "SysIni", "REXXUTIL", "SysIni"

                    /* name of the REXX cmd to copy the options       */
  outFile = "SETLKUP.CMD"

                    /* carriage return and linefeed values            */
  crLF    = "0D0A"x

                    /* show a little message                          */
  call LineOut , "Creating the file"
  call LineOut , "  " || outFile
  call CharOut , "to copy the lockup options of this machine to other",
                 "machines  ... "

                   /* delete an existing target file                  */
  "@del " outFile "2>NUl 1>NUL"

                    /* get the current lockup options                 */
  curLockupOptions = SysIni( "USER", "PM_Lockup", "LockupOptions" )

                    /* create the REXX cmd to copy this options to    */
                    /* another machine                                */
  call LineOut outFile ,,
    "/* REXX cmd to set the lockup options */"             || crLF || ,
    "/* created on " || date() || " at " || time() || " */"|| crLF || ,
    ""                                                     || crLF || ,
    "  call rxFuncAdd 'SysIni', 'REXXUTIL', 'SysIni'"      || crLF || ,
    ""                                                     || crLF || ,
    "  call SysIni 'USER', 'PM_Lockup', 'LockupOptions',," || crLF || ,
    "            '" || c2x( curLockupOptions ) || "'x"     || crLF || ,
    ""                                                     || crLF || ,
    "  '@setboot /IBD:C:'"                                 || crLF || ,
    ""

  call lineOut , " done."

Note that the reboot is necessary to make the changes active!

Set or get the WPS lockup password
 
/*                                                                    */
/* sample REXX functions to set and get the password for the WPS      */
/* lockup feature                                                     */
/*                                                                    */
/* Author: Ned Konz (see EMail Addresses)                             */
/*                                                                    */
/* History:                                                           */
/*   12.12.1996 /bs                                                   */
/*   - added code to distinguish between OS/2 2.1(1) and OS/2 WARP    */
/*     (Tested with OS/2 WARP 3 and OS/2 WARP 4)                      */
/*   - added code to handle 'Password not yet set' situations         */
/*                                                                    */
/*                                                                    */
/* note:                                                              */
/*   see also Changing the Lockup page entry,                         */
/*   Setup strings for WPDesktop objects                              */
/*   and Activating Lockup now                                       */
/*                                                                    */

  call rxfuncadd "SYSLOADFUNCS", "REXXUTIL", "SYSLOADFUNCS"
  call sysloadfuncs

                        /* check the OS/2 version                     */
  if SysOS2Ver() > "2.11" then
  do
                        /* current OS/2 version is WARP 3 or newer    */
    LockUpOptionString = "LockupOptions"
    LockUpApplication = "PM_Lockup"
  end /* if SysOS2Ver() > "2.11" then */
  else
  do
                        /* current OS/2 version is v2.11 or older     */
    LockUpOptionString = "Lockup_options3"
    LockUpApplication =  "Lock Up Workplace"
  end /* else */

  inival = SysIni( "USER", LockupApplication, LockUpOptionString )

  if iniVal = "ERROR:" then
  do
                        /* Never opened the lockup page of the        */
                        /* desktop setup menu until now ->            */
                        /* The entry for the Lockup page is missing   */
                        /* in the INI file                            */
    say "Error: No screen saver password set!"
    say "Hint:  Use the setup menu of the desktop to set an" ,
                     "initial password."
    rc = 255
  end /* if IniVal = "ERROR:" then */
  else
  do
    say "The current password is: '" || GetPassword(inival) || "'"
    say
    say "Enter the new password (blank line to quit)"

    newpass = lineIn()

    if length( newpass ) <> 0 then
    do
      inival = SetPassword( inival, newpass )
      rc = SysIni( "USER", LockupApplication, LockupOptionString, inival )

      say "Password changed. Re-boot is needed to make permanent."
    end /* if length( newPass ) <> 0 then */
  end /* else */

EXIT rc

/* ------------------------------------------------------------------ */
/* function: given a single character encrypted key, return           */
/*           decrypted key                                            */
/*                                                                    */
/* call:     DecrypKey encrypted_key                                  */
/*                                                                    */
/* where:    encrypted_key - encrypted character                      */
/*                                                                    */
/* returns:  decrypted key                                            */
/*                                                                    */
/* note:     called by GetPassword()                                  */
/*                                                                    */
DecryptKey: PROCEDURE
  RETURN d2c( c2d( arg( 1 ) ) / 3 - 12 )

/* ------------------------------------------------------------------ */
/* function: get the password from the INI file entry                 */
/*                                                                    */
/* call:     GetPassword iniFileEntry                                 */
/*                                                                    */
/* where:    iniFileEntry - entry from the INI file                   */
/*                                                                    */
/* returns:  decrypted password                                       */
/*                                                                    */
/*                                                                    */
GetPassword: PROCEDURE

  inival = arg( 1 )
                        /* encrypted key                              */
  ekey = substr( inival, 7, 1 )

                        /* real key                                   */
  key = DecryptKey( ekey )

                        /* NUL term.                                  */
  parse value substr( inival, 11, 16 ) WITH val "00"x

  key = copies( key, length( val ) )

RETURN bitxor( val, key )

/* ------------------------------------------------------------------ */
/* function: create an INI file entry to change the password          */
/*                                                                    */
/* call:     SetPassword iniFileEntry, newPassword                    */
/*                                                                    */
/* where:    iniFileEntry - entry from the INI file                   */
/*           newPassword - new password                               */
/*                                                                    */
/* returns:  new entry for the INI file                               */
/*                                                                    */
/*                                                                    */
SetPassword: PROCEDURE
  inival = arg( 1 )

  parse upper value arg( 2 ) WITH newpass

                    /* encrypted key: "27"x                           */
  ekey = "27"x

                    /* real key: "01"x                                */
  key = copies( DecryptKey( ekey ), length( newpass ) )

  key = overlay( bitxor( key,newpass ), copies( "00"x, 16 ) )

  inival = overlay( key, inival, 11 )

RETURN overlay( ekey, inival, 7 )
Disable or enable the registration reminder

To disable or enable the registration reminder you may set the following keys (WARP 4 only!) : File OS2.INI

Application PM_Workplace:ART

Key DISABLED

Value fully qualified name of ARTCHRON.EXE with a trailing null byte

Description If this key is set, the registration reminder is disabled

Created ?

Deleted ?

Example "C:\OS2\ART\ARTCHRON.EXE"


File OS2.INI

Application PM_Workplace:ART

Key ENABLED

Value fully qualified name of ARTCHRON.EXE with a trailing null byte

Description If this key is set, the registration reminder is enabled

Created ?

Deleted ?

Example "C:\OS2\ART\ARTCHRON.EXE"


Source: Ralf Ulrich (see EMail Addresses) Note: You can also delete the two keys to fully disable the registration reminder. Or use the Install Object - Inventory in the new folder "C:\OS2\INSTALL\Installed Features" (where C: is your boot drive) to uninstall it completely.

Double-Click on to open the parent folder of the "Install Object - Inventory" folder right now.

Default Settings for WPUrl Objects

The defaults for the WPUrl objects are saved in the application WPURLDEFAULTSETTINGS in the file OS2.INI (WARP 4 only!, see also WPUrl) File OS2.INI

Application WPURLDEFAULTSETTINGS

Key see WPUrl

Value see WPUrl

The values must have a trailing zero byte, NO is translated to "0" and YES is translated to "1"

Description defaults for the WPUrl objects

Created ?

Deleted ?

Example -

General routines for the samples
 

/* ================================================================== */
/*    This chapter contains various routines needed by the samples    */
/*                        from the WPS section                        */
/* ================================================================== */

/* ------------------------------------------------------------------ */
/* function: show the data of an object                               */
/*                                                                    */
/* usage:    ShowObjectData [objectID | objectHandle] ,,              */
/*                          indent, indent1                           */
/*                                                                    */
/* where:    objectID - object ID (e.g. "<WP_DESKTOP>"                */
/*           objectHandle - object Handle (e.g. "#340056")            */
/*           indent - indent for all lines except the first           */
/*           indent1 - indent for the first line                      */
/*                                                                    */
/* returns:  1 - ok                                                   */
/*           0 - object not found                                     */
/*          -1 - parameter missing                                    */
/*                                                                    */
/* Note:  This routine needs Henk Kelders excellent DLL WPTOOLS.DLL!  */
/*                                                                    */
/*              This routine only retrieves the setup strings         */
/*              supported by the DLL WPTOOLS.DLL (see the file        */
/*              WPTOOLS.TXT from the WPTOOLS package)!!!              */
/*                                                                    */
/*                                                                    */
ShowObjectData: PROCEDURE
  parse arg curObjectHandle , indent , indent1

  if rxFuncQuery( "WPToolsQueryObject" ) then
  do
                    /*  load WPTOOLS functions                        */
    call RxFuncAdd "WPToolsLoadFuncs", "WPTOOLS", "WPToolsLoadFuncs"
    call WPToolsLoadFuncs
  end /* if rxFuncQuery( ... */

  iRetCo = -1
  if curObjectHandle <> 0 then
  do
    iRetco = WPToolsQueryObject( curObjectHandle,,
                                 "szClass",,
                                 "szTitle",,
                                 "szSetupString",,
                                 "szLocation" )
    if iRetco then
    do
                /* get the object ID of this object (if it exists)    */
      parse value ( szSetupString || ";" ) WITH  "OBJECTID=" objectID ";"
      if objectID = "" then
        objectID = "[no object ID, the object handle is " || ,
                   curObjectHandle || "]"
      call lineOut, copies( " " ,indent1 ) || objectID

      call lineOut, copies( " ", indent  ) || "Classname   : " || szClass
      call lineOut, copies( " ", indent  ) || "Title       : " || szTitle
      call lineOut, copies( " ", indent  ) || "Location    : " || szLocation

                    /* use formatted output for the setup string      */
      call SplitSetupString 80 - ( indent + 15 ) , szSetupString

      call LineOut , copies( " ", indent ) || "Setupstring : " || ,
                     SetupStrStem.1

      do n = 2 to SetupStrStem.0
        if n <> SetupStrStem.0 then
          call LineOut , copies( " " ,indent + 14 ) || SetupStrStem.n
      end /* do n = 2 to SetupStrStem.0 */

    end /* if iRetCo then */
    else
      call lineOut, copies( " ", indent1 ) || "Error: Object " || ,
                    curObjectHandle || " not found!"

  end /* if curObjectHandle <> 0 then */

RETURN iRetCo

/* ------------------------------------------------------------------ */
/* Function: split a setup string into parts with a maximum length    */
/*                                                                    */
/* call:     SplitSetupString length , setupString                    */
/*                                                                    */
/* where:    length - max. length for the parts                       */
/*           setupString - setup String                               */
/*                                                                    */
/* returns:  1                                                        */
/*                                                                    */
/*           SetupStrStem.0 - no. of parts                            */
/*           SetupStrStem.# - part 1 to n                             */
/*                                                                    */
/* Note:     The setup string is split at semicolons (;). If a        */
/*           part of the setup string is too long, it is split at     */
/*           commas (,).                                              */
/*           Setupstrings (and parts of them) without a semicolon and */
/*           a comma are not split.                                   */
/*                                                                    */
SplitSetupString: PROCEDURE expose setupStrStem.
  parse arg thisLength, setupString

  SetupStrStem. = ""
  SetupStrStem.0 = 0
  j = 1

  do until setupString = ""

    parse var setupString curPart ";" setupString

    select
      when length( curPart ) >= thisLength then
      do

        if length( SetupStrStem.j ) <> 0 then
          j = j + 1

        curPart = curPart || ";"

        do until curPart = ""
          parse var curPart curTPart "," curPart

          if ( length( SetupStrStem.j ) + length( curTPart ) + 1 >= thisLength ) & ,
             length( SetupStrStem.j ) <> 0 then
            j = j +1

          if curPart = "" then
            SetupStrStem.j = SetupStrStem.j || curTPart
          else
            SetupStrStem.j = SetupStrStem.j || curTPart || ","

        end /* until curPart = "" */

      end /* when */

      when length( SetupStrStem.j ) + 1 + length( curPart ) > thisLength then
      do
        j = j + 1
        SetupStrStem.j = curPart || ";"
      end /* when */

      otherwise
      do
        SetupStrStem.j = SetupStrStem.j || curPart || ";"
      end /* otherwise */

    end /* select */
  end /* do until setupString = "" */

  setupStrStem.0 = j

RETURN 1

OS2SYS.INI

This section contains information about some entries of the file OS2SYS.INI.

Print to a file

To print to a file bypassing the prompt for the filename you can create a new port in your OS2SYS.INI file:

/* add an output file port into OS2SYS.INI                            */
  call RxFuncAdd "SysIni", "RexxUtil", "SysIni"
     call SysIni "SYSTEM", "PM_SPOOLER_PORT", "c:\prtout.prn",,
           ";" || "00"x

After the execution of this little program you can assign the newly created port to any printer object.

Note: Every new print output overwrites the existing file - you can't append the output to the file. Well, at least I haven't found a way to do this.

Source: OS/2 2.11 Power Techniques

Add new LPT Ports

Following is a sample REXX program to create additional LPT ports for the print spooler. This code is from a program called LPT49.cmd from the Keller Group (see http://www.cds-inc.com/techsprt/miscfxdl.html ).

(see also Get a list of all printers)

  call charout, 'Adding LPT4 through LPT9 to system ini '
  call RxFuncAdd 'SysIni', 'RexxUtil', 'SysIni'
  do i = 4 to 9
    call charout, '.'
    call SysIni 'SYSTEM', 'PM_SPOOLER_PORT', 'LPT' || i, ';' || '00'x
  end /* do i = 4 to 9 */
  say ' done.'

To use the ports in WinOS/2 also add the lines

LPT4:=
LPT5:=
LPT6:=
LPT7:=
LPT8:=
LPT9:=
LPT4.OS2=
LPT5.OS2=
LPT6.OS2=
LPT7.OS2=
LPT8.OS2=
LPT9.OS2=

to the section [ports] of the file \OS2\MDOS\WINOS2\WIN.INI.

Add new COM Ports

Following is a sample REXX program to create additional COM ports for the print spooler. (based on Add new LPT Ports found in a public news group)

  call charout, 'Adding COM5 through COM8 to system ini '
  call RxFuncAdd 'SysIni', 'RexxUtil', 'SysIni'

  do i = 5 to 8
    call charout, '.'
    call SysIni 'SYSTEM', 'PM_SPOOLER_PORT', 'COM' || i, ';' || '00'x
  end /* do i = 5 to 8 */
  say ' done.'

It maybe(!) possible to use the ports in WinOS/2 also if you add the lines

COM5:=9600,n,8,1,x
COM6:=9600,n,8,1,x
COM7:=9600,n,8,1,x
COM8:=9600,n,8,1,x
COM9:=9600,n,8,1,x

to the section [ports] of the file \OS2\MDOS\WINOS2\WIN.INI.

Add new sound schemes in WARP 4
==REXX program to create new sound schemes in WARP 4==

Following is a sample REXX program to create a new sound scheme (see also Add new sound schemes in WARP 4):

/* ------------------------------------------------------------------ */
/*  SetSound.CMD                                                      */
/*    Sets up a sound scheme by writing the appropriate               */
/*    entries into the specified system INI file.                     */
/*                                                                    */
/*  Syntax:                                                           */
/*    SetSound  {filespec}                                            */
/*                                                                    */
/*  Source:                                                           */
/*   Personal Systems Issue 11/96 (online edition)                    */
/*                                                                    */
/* ------------------------------------------------------------------ */
/* Set the sound scheme variables                                     */
/* ------------------------------------------------------------------ */

  Title =   "MySoundScheme"
  KeyName = "PM_SOUNDS_MYSOUNDS"

  Event.0  = 13
  Event.1  = "?:\mmos2\sounds\mysounds\my_warn.wav"
  Event.2  = "?:\mmos2\sounds\mysounds\my_info.wav"
  Event.3  = "?:\mmos2\sounds\mysounds\my_err.wav"
  Event.4  = "?:\mmos2\sounds\mysounds\my_opnw.wav"
  Event.5  = "?:\mmos2\sounds\mysounds\my_clsw.wav"
  Event.6  = "?:\mmos2\sounds\mysounds\my_drag.wav"
  Event.7  = "?:\mmos2\sounds\mysounds\my_drop.wav"
  Event.8  = "?:\mmos2\sounds\mysounds\my_sstr.wav"
  Event.9  = "?:\mmos2\sounds\mysounds\my_ssht.wav"
  Event.10 = "?:\mmos2\sounds\mysounds\my_shrd.wav"
  Event.11 = "?:\mmos2\sounds\mysounds\my_lock.wav"
  Event.12 = "?:\mmos2\sounds\mysounds\my_alck.wav"
  Event.13 = "?:\mmos2\sounds\mysounds\my_prer.wav"

/* ------------------------------------------------------------------ */
/* Get the input arguments                                            */
/* ------------------------------------------------------------------ */

  Parse Upper Arg fSpec

/* ------------------------------------------------------------------ */
/*  Check if the REXX external functions are registered.              */
/*  If not, then register them so we can use them                     */
/* ------------------------------------------------------------------ */

  if RxFuncQuery("SysLoadFuncs") then
  do
    Call RxFuncAdd "SysLoadFuncs", "RexxUtil", "SysLoadFuncs"
    Call SysLoadFuncs
  end /* if */

/* ------------------------------------------------------------------ */
/* Set up the filespec for the INI file                               */
/* ------------------------------------------------------------------ */
  if fSpec = "" then
  do
    IniFile = "SYSTEM"
  end /* if fSpec = "" then */
  else
  do

/* ------------------------------------------------------------------ */
/* Parse the input filespec into its component parts                  */
/* ------------------------------------------------------------------ */

    tDrive = filespec("drive",fSpec)
    tPath  = filespec("path",fSpec)
    tName  = filespec("name",fSpec)

/* ------------------------------------------------------------------ */
/* Get the local drive and current directory                          */
/* ------------------------------------------------------------------ */

    LocalCurDir = directory()
    LocalDrive = substr( LocalCurDir, 1, 1 )
    lDrive = LocalDrive||":"

    LocalDir = substr(LocalCurDir, 3)
    lDir = LocalDir||"\"

/* ------------------------------------------------------------------ */
/* Set the INI file spec                                              */
/* ------------------------------------------------------------------ */

    if tDrive = "" then
      tDrive = lDrive

    if tPath = "" then
      tPath = lDir

    IniFile = tDrive||tPath||tName
  end /* else */

/* ------------------------------------------------------------------ */
/* Set the keys for the new sound scheme we're adding                 */
/* ------------------------------------------------------------------ */

  results = SysIni( IniFile, "PM_SOUND_SCHEMES_LIST", Title, KeyName )

  if results = "ERROR:" then
  do
    say "SetSound ERROR:" ,
        "Unable to set PM_SOUND_SCHEMES_LIST in the INI file"
    exit
  end /* if */
  else
  do
    say "SetSound: The following keywords have been set in the INI file:" ,
         IniFile
    say "SetSound: PM_SOUND_SCHEMES_LIST ," Title "," KeyName
  end /* else */

/* ------------------------------------------------------------------ */
/* For the KeyName, set the sounds for the events                     */
/* ------------------------------------------------------------------ */

  do i=1 to Event.0

    Type = i-1
    results = SysIni( IniFile, KeyName, Type, Event.i )

    if results = "ERROR:" then
    do
      say "SetSound ERROR: Unable to set Type" Type "for the file" ,
          Event.i "in the INI file"
    end /* if */
    else
    do
      say "SetSound: System Event Type" Type " = " Event.i
    end /* else */

  end /* do i=1 to Event.0 */

exit 0

/* ------------------------------------------------------------------ */
/* End of REXX script                                                 */
/* ------------------------------------------------------------------ */

How to wait in the STARTUP.CMD until the WPS is up

If you're using WPS-related code in your STARTUP.CMD, you should use the following code (or use the function �SysWaitForShell from the new REXXUTIL DLL) to wait until the WPS is up:

  call rxFuncAdd 'SysLoadFuncs', 'REXXUTIL', 'SysLoadFuncs'
  call SysLoadFuncs

  rc = SysIni('USER', 'PM_InstallObject', 'ALL:', 'stem')
  do while rc \= 'ERROR:'
    call SysSleep 2
    rc = SysIni('USER', 'PM_InstallObject', 'ALL:', 'stem')
  end /* do while rc \= 'ERROR:' */

  /* add WPS related code here */

Change the WPS archive flag

The WPS archive flag is saved in the file \OS2\BOOT\ARCHBASE.$$$ at the offset 0xCF (Use 208 dec. for �CharOut in REXX programs. This is necessary because REXX counts beginning with 1). To turn the ARCHIVE feature on, set this byte to 0x01; to turn it off set it to 0x00 (tested with OS/2 WARP and OS/2 WARP Connect, see example program below).

The name of the path for the archive is saved as ASCIIZ string in the same file at the offset 0x06 (use 7 dec for �CharOut in REXX programs). The maximum length for the path is 200. (see also Change the OS/2 recovery screen options)

Source: Peter Bunney (see EMail Addresses)

Note: According to some messages on Usenet, the offset of these bytes is different in various versions of WARP with Fixpacks applied. I can't say if that is true or not -- but don't forget that the format of this file is not documented!

     
    /*                                                                    */
    /* Program Title: swBackup.CMD                                        */
    /*                                                                    */
    /* Program Purpose: get, set or clear the archive bit in the          */
    /*                  desktop settings                                  */
    /*                                                                    */
    /* Author: Peter Bunney 100411.20@compuserve.com                      */
    /*         (see EMail Addresses)                                      */
    /*                                                                    */
    /* History                                                            */
    /*   Date Written: 16 dec 95                                          */
    /*                                                                    */
    /*   Date Updated: 18 dec 95                                          */
    /*    - added parameter /bs                                           */
    /*    - added some error checking /bs                                 */
    /*    - changed the name to the 8.3 convention                        */
    /*                                                                    */
    /* Usage:                                                             */
    /*   swBackup {ON|OFF|STATUS} {bootDrive}                             */
    /*                                                                    */
    /* Where:                                                             */
    /*   ON        = switch archive feature ON                            */
    /*   OFF       = switch archive feature OFF                           */
    /*   STATUS    = get the current status of the archive feature (def.) */
    /*   bootDrive = boot drive (e.g. "C:")                               */
    /*               def.: use environment variable RUNWORKPLACE          */
    /*                                                                    */
    /* Returns:                                                           */
    /*   parameter ON or OFF: 0 if successful                             */
    /*   parameter STATUS: 0 - archive feature is off,                    */
    /*                     1 - archive feature is on                      */
    /*   else                                                             */
    /*     255 - error                                                    */
    /*                                                                    */

                            /* init the return code                       */
      retCode = 255

                            /* get the parameter                          */
      parse arg action bootdrive .

                            /* check the parameter, use defaults if       */
                            /* necessary                                  */
      if bootDrive = "" then
        bootDrive = left( value( "RUNWORKPLACE",, "OS2ENVIRONMENT" ),1 )
      bootDrive = left( bootDrive,1 ) || ":"

      if action = "" then
        action = "STATUS"
      action = translate( action )

                            /* file used by the WPS to save the current   */
                            /* status                                     */
      Archivefilename = bootDrive || "\os2\boot\archbase.$$$"

      if stream( ArchiveFileName, "c", "QUERY EXISTS" ) <> "" then
      do
                            /* change file attributes                     */
        "@attrib -r " ArchiveFilename "2>NUL 1>NUL"
        if rc = 0 then
        do

                            /* process the appropriate action             */
          select

            when action = "ON" then
            do
                            /* turn the archive feature ON                */
              if stream( ArchiveFileName, "c", "OPEN WRITE" ) = "READY:" then
                if charout( ArchiveFilename, x2c( 01 ), 208 ) = 0 then
                  retCode = 0
              call stream ArchiveFileName, "c", "CLOSE"
            end /* when */

            when action = "OFF" then
            do
                            /* turn the archive feature OFF               */
              if stream( ArchiveFileName, "c", "OPEN WRITE" ) = "READY:" then
                if charout( ArchiveFilename, x2c( 00 ), 208 ) = 0 then
                  retCode = 0
              call stream ArchiveFileName, "c", "CLOSE"
            end /* when */

            when action = "STATUS" then
            do
                            /* get the status of the archive feature      */
              if stream( ArchiveFileName, "c", "OPEN READ" ) = "READY:" then
                retCode = c2x( charin( ArchiveFilename,208,1 ) )
              call stream ArchiveFileName, "c", "CLOSE"
            end /* when */

            otherwise
            do
              say "Error: Invalid action parameter <" || action "> found!"
              retCode = 255
            end /* otherwise */

          end /* select */

                              /* reset file attributes                      */
          "@attrib +r " ArchiveFilename "2>NUL 1>NUL"
        end /* if rc = 0 then */
        else
          say "Error changing the attributes of <" || ArchiveFileName || ">!"

      end /* if stream( ... */
      else
        say "File <" || ArchiveFileName || "> not found!"

    exit retCode

Change the OS/2 recovery screen options

The flag indicating the status of the Display recovery choices at each restart checkbox (this is the Archive system files checkbox on the Archive page in the Desktop setup menu) is saved in the file \OS2\BOOT\ARCHBASE.$$$ in the byte at the offset 0xD9. Set this byte to 0x01 to turn the feature on; 0x00 turns the feature off.

The number of seconds to wait is saved as word in the same file at the offset 0xDD. (tested with OS/2 WARP and OS/2 WARP Connect, see example program below). (see also Change the WPS archive flag )

 
/*                                                                    */
/* Name:     Archive.CMD                                              */
/*                                                                    */
/* Function:                                                          */
/*   Get, set or clear the                                            */
/*     "Display recovery choices at each restart"                     */
/*   feature of OS/2                                                  */
/*                                                                    */
/* Usage:                                                             */
/*   archive  {ON{:time}|OFF{:time}|STATUS} {bootDrive}               */
/*                                                                    */
/* Where:                                                             */
/*   ON        = switch the feature ON                                */
/*   OFF       = switch the feature OFF                               */
/*               time - time to wait in seconds                       */
/*                      (def. use the current setting)                */
/*   STATUS    = get the current status of the feature (default)      */
/*   bootDrive = bootDrive (default: uset the environment variable    */
/*               RUNWORKPLACE)                                        */
/*                                                                    */
/* Returns:                                                           */
/*   parameter ON or OFF:                                             */
/*     0 - successful                                                 */
/*     else error                                                     */
/*                                                                    */
/*   parameter STATUS:                                                */
/*     if called from the command line:                               */
/*       0 - feature is off                                           */
/*       1 - feature is on                                            */
/*     else error                                                     */
/*                                                                    */
/*     if called from another REXX program:                           */
/*       x n                                                          */
/*     where                                                          */
/*       x - 0 - feature is off                                       */
/*           1 - feature is on                                        */
/*         else error                                                 */
/*       n - timeout value in seconds                                 */
/*                                                                    */
/*                                                                    */
/*                                                                    */
/* Credits:                                                           */
/*   Thanks to Peter Bunney for pointing me to the file               */
/*   \OS2\BOOT\ARCHBASE.$$$.                                          */
/*   (see EMail Addresses)                                            */
/*                                                                    */
/* History:                                                           */
/*   14.04.1996 /bs                                                   */
/*     - initial release for RXT&T v2.20                              */
/*                                                                    */
/* Notes:                                                             */
/*   -                                                                */
/*                                                                    */
/* (c) 1996 Bernd Schemmer, Germany, EMail: Bernd.Schemmer@gmx.de     */
/*                                                                    */
                        /* init the return code                       */
  retCode = 0

                        /* get the parameter                          */
  parse arg action bootdrive .

                        /* check the parameter, use defaults if       */
                        /* necessary                                  */
  if bootDrive = "" then
    bootDrive = left( value( "RUNWORKPLACE",, "OS2ENVIRONMENT" ),1 )
  bootDrive = left( bootDrive,1 ) || ":"

                        /* default action is STATUS                   */
  if action = "" then
    action = "STATUS"

                        /* check the timeout value                    */
  parse var action action ":" newTimeOut
  action = translate( strip( action ) )

  if newtimeOut <> "" then
    if datatype( newtimeOut ) = "NUM" then
    do
      if NewtimeOut >= 0 & newtimeOut <= 999 then
        newtimeOut = translate( "12", d2c( newtimeOut,2 ), "21", "00"x )
      else
        retCode = 255 "Error: Invalid timeout value <" || NewtimeOut || "> found!"
    end /* if */
    else
      retCode = 255 "Error: Invalid timeout parameter <" || NewtimeOut || "> found!"

                        /* get the call type                          */
  parse upper source . callType .

                        /* file used by the OS/2 to save the current  */
                        /* status                                     */
  Archivefilename = bootDrive || "\os2\boot\archbase.$$$"

  if retCode = 0 then
    if stream( ArchiveFileName, "c", "QUERY EXISTS" ) <> "" then
    do
                        /* change file attributes                     */
      "@attrib -r " ArchiveFilename "2>NUL 1>NUL"
      if rc = 0 then
      do
                        /* process the appropriate action             */
        select

          when action = "ON" | action = "OFF" then
          do
                        /* turn the feature ON or OFF                 */

            if stream( ArchiveFileName, "c", "OPEN WRITE" ) = "READY:" then
            do
              newFlagValue = x2c( ( action = "ON" ) )

                        /* change the flag                            */
              retCode = charOut( ArchiveFilename, newFlagValue, 218 )

                        /* set the new timeout value                  */
              if NewtimeOut <> "" & retCode = 0 then
                retCode = charOut( ArchiveFileName, NewTimeOut, 222 )

            end /* if stream( ArchiveFileName, ... */

            call stream ArchiveFileName, "c", "CLOSE"
          end /* when */

          when action = "STATUS" then
          do
                        /* get the status of the feature              */
            if stream( ArchiveFileName, "c", "OPEN READ" ) = "READY:" then
            do
                        /* get the flag value                         */
              flagValue = c2x( charin( ArchiveFilename,218,1 ) )

                        /* get & convert the timeout value            */
              timeOut = translate( "12", charIn( ArchiveFileName,222,2 ), "21" )
              timeOut = x2d( c2x( timeOut ) )

              retCode = flagValue timeOut
            end /* if */

            call stream ArchiveFileName, "c", "CLOSE"
          end /* when */

          otherwise
          do
            retCode = 255 "Error: Invalid action parameter <" || action || "> found!"
          end /* otherwise */

        end /* select */

                        /* reset file attributes                      */
        "@attrib +r " ArchiveFilename "2>NUL 1>NUL"
      end /* if rc = 0 then */
      else
        retCode = 255 "Error changing the attributes of <" || ArchiveFileName || ">!"

    end /* if stream( ... */
    else
      retCode = 255 "File <" || ArchiveFileName || "> not found!"

                        /* process the return code                    */
  parse var retCode exitCode errorMessage

  if exitCode > 1 then
  do
                        /* display the error message                  */
    say errorMessage
                        /* remove the error message from the return   */
                        /* code                                       */
    retCode = exitCode
  end /* if exitCode > 1 then */

  if callType = "COMMAND" then
    retCode = word( retCode,1 )

exit retCode