Regina REXX for Win32™

Copyright © 1995 Microsoft Corporation. All rights reserved.

Written for Microsoft Corporation by Ataman Software, Inc. (info@ataman.com).

This document describes issues specific to the Win32 port of Regina REXX.

Table of Contents

Installation4

Usage4

OLE Automation Support4

w32CreateObject4

w32ReleaseObject5

w32CallFunc, w32CallProc5

w32GetProperty6

w32PutProperty6

w32GetObject7

w32GetSubObj7

Win32 Registry Functions7

w32ExpandEnvironmentStrings8

w32RegCloseKey8

w32RegConnectRegistry8

w32RegCreateKey9

w32RegDeleteKey9

w32RegDeleteValue10

w32RegEnumKey10

w32RegEnumValue10

w32RegFlushKey11

w32RegGetKeySecDesc11

w32RegLoadKey12

w32RegOpenKey12

w32RegQueryInfoKey12

w32RegQueryValue13

w32RegQueryValue13

w32RegRestoreKey14

w32RegSaveKey14

w32RegSetKeySecDesc15

w32RegSetValue15

w32RegUnLoadKey16

Win32 Event Log Functions16

w32BackupEventLog16

w32ClearEventLog17

w32CloseEventLog17

w32FindEventLogEntry17

w32GetEventCategory18

w32GetEventData18

w32GetEventID18

w32GetEventNumStrings19

w32GetEventString19

w32GetEventTimeGenerated19

w32GetEventTimeWritten20

w32GetEventType20

w32GetNumberOfEventLogRecords20

w32OpenBackupEventLog21

w32OpenEventLog21

w32WriteEventLog21

Known Limitations22

Installation

Installation is simple, just copy REXX.EXE to a directory that is in your PATH.

Alternatively, you can run the SETUP.CMD file, this file runs REXX on a script called: INS-REXX. This script will prompt for a directory name, create the directory, then copy REXX.EXE to that directory. Finally, it will add that directory to your PATH environment variable. You will need to logoff and log back on before this new PATH setting takes effect.

Usage

Prepare a script file using NOTEPAD.EXE, or other text file editor. To execute the script, run REXX.EXE with the name of the script file.

Example:

rexx myscript.rexx

A new feature in CMD.EXE under Windows NT 3.51 allows the same script above to

be started as:

Example:

myscript.rexx

For information on how to do this, see the documentation under the /X switch when you type CMD /?.

OLE Automation Support

The OLE Automation support closely parallels that found in Microsoft Visual Basic 3.0.

The “OLEAUTO” subdirectory contains three REXX files that use OLE Automation with Microsoft Word, Microsoft Excel and a sample application called DspCalc2. See the “README.TXT” file in that subdirectory for more information on the samples.

w32CreateObject

The w32CreateObject function is the most common way to access an OLE Automation object. This function launches (if necessary) the OLE Automation server and returns a handle through which the OLE Automation object can be manipulated.

Syntax:

ObjectHandle = w32CreateObject ( OLEAutomationServerClassName )

Example:

wrd = w32CreateObject(“Word.Basic”)

w32ReleaseObject

The w32ReleaseObject subroutine is called to free up the resources obtained when an OLE Automation object was created or otherwise obtained. If you do not call w32ReleaseObject, the resources will remain in use until REXX exits.

Syntax:

call w32ReleaseObject ObjectHandle

Example:

call w32ReleaseObject wrd

Valid object handles are those obtained by calls to w32CreateObject, w32GetObject, w32GetSubObj, w32GetProperty and w32CallFunc.

w32CallFunc, w32CallProc

The w32CallFunc function is used to access a method of an OLE Automation object where you expect to receive a return value. If no return value is needed, use w32CallProc instead.

Syntax:

ReturnValue = w32CallFunc ( ObjectHandle, MethodName,[ TypeList ], [ Argument, ... ] ) w32CallProc ( ObjectHandle, MethodName, [ TypeList ], [ Argument, ... ] )

Examples:

SalesValue = w32CallFunc(wrd, “GetMergeField$”, , “Sales”) w32CallProc(wrd, “FileNew”, ‘si’, “Normal”, 0)

Optional arguments to the method can be omitted, leaving only the corresponding “,” as in the example for w32CallFunc above.

The TypeList is optional, and for many OLE Automation servers is unnecessary because automatic type conversion is usually done by the OA server. REXX is an untyped language and all its data are stored as strings, thus, if TypeList is omitted, all arguments will be sent to the OA server as strings. However some OA servers, such as Microsoft Word, require correct typing of parameters. The TypeList is simply a series of characters that define the type of each argument that follows. There should be as many type characters list in the TypeList as there are arguments listed. The type character for an omitted argument is ignored, but must be present. (I usually use ‘ ‘ as the type character for omitted arguments.)

Type Required

Type Character

Boolean

b

Currency

c

Date

d

Integer (16-bit)

i

Integer (32-bit)

I

Object Handle

o

Real Number (4 byte)

r

Real Number (8 byte)

R

String

s

w32GetProperty

The w32GetProperty function returns the value of a named property from an OLE Automation object.

Syntax:

ReturnValue = w32GetProperty ( ObjectHandle, PropertyName )

Example:

MyCaption = w32GetProperty(xl, “Caption”)

w32PutProperty

The w32PutProperty subroutine sets the value of a named property in an OLE Automation object.

Syntax:

call w32PutProperty ObjectHandle, PropertyName,Type, Value

Example:

call w32PutProperty xl, “Caption”, , “Change Window Title”

The Type is optional, and is defined using the same characters as TypeList in w32CallProc. The Type is the data type in which the OLE Automation server requires Value to be expressed.

w32GetObject

The w32GetObject function is similar to w32CreateObject. It gets an object that previously exists either saved in a disk file, or in already running OLE Automation server. It returns a handle through which the OLE Automation object can be manipulated.

Syntax:

ObjectHandle = w32GetObject ( [ Filename ], [ OAServerClassName ] )

Example:

xl = w32GetObject(“D:\MYDIR\SPREADSHEET.XLS”)

w32GetSubObj

Some OLE Automation servers, such as Microsoft Excel, have methods that return handles to sub-objects. The w32GetSubObj function is a bit of syntactic sugar that works exactly like w32CallFunc. The only difference is that the return value must be the handle of an object.

Syntax:

ObjectHandle = w32GetSubObj ( ObjectHandle, MethodName,[ TypeList ], [ Argument, ... ] )

Example:

wbs = w32GetSubObj(xl, “WorkBooks”)

Object handles obtained by w32GetSubObj should be released by w32ReleaseObject when no longer needed.

Win32 Registry Functions

The Win32 registry functions closely parallels the corresponding C functions found in the Win32 API. The descriptions below are fairly brief. Consult the Win32 SDK documentation for more detailed information.

The “W32FUNCS” subdirectory contains an example file: “registry.rexx” that uses the registry functions. See the “README.TXT” file in that subdirectory for more information on this example.

WARNING: The Win32 Registry contains information vital to the functioning of your system. The functions below should be used with caution.

w32ExpandEnvironmentStrings

The w32ExpandEnvironmentStrings function expands environment variables (names are denoted by preceding and trailing ‘%’) in the string argument using the process’ environment. It returns the expanded string.

Syntax:

expanded_string = w32ExpandEnvironmentStrings ( string )

Example:

path = w32ExpandEnvironmentStrings(“PATH=%PATH%”) say path /* says: PATH=C:\WINNT\system32;C:\WINNT;... */

w32RegCloseKey

The w32RegCloseKey subroutine closes a key handle returned by w32RegOpenKey, w32RegConnectRegistry, or w32RegCreateKey.

Syntax:

call w32RegCloseKey KeyHandle

Example:

call w32RegCloseKey hkey;

w32RegConnectRegistry

The w32RegConnectRegistry function opens a registry key on a remote host. It returns a handle to the remotely opened key.

Syntax:

hkeyRet = w32RegConnectRegistry ( hostname, hkey )

Example:

hk = w32RegConnectRegistry(“\\mainserver”, “HKEY_LOCAL_MACHINE”)

Hkey should be one of the string constants HKEY_LOCAL_MACHINE or HKEY_USERS.

w32RegCreateKey

The w32RegCreateKey creates or opens a subkey under a registry key. It returns a handle to the subkey created or opened.

Syntax:

hkeyRet = w32RegCreateKey ( hkey, subkeyname )

Example:

hk = w32RegCreateKey(“HKEY_LOCAL_MACHINE”,“Software\Microsoft\NewProduct”)

Hkey should be a previously obtained key handle or one of the string constants: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

w32RegDeleteKey

The w32RegDeleteKey subroutine deletes the key subkey, which must be located under the key hkey. All values under subkey are also deleted.

Syntax:

call w32RegDeleteKey hkey, subkey

Example:

call w32RegDeleteKey hk, “WidgetTuningParameters”

Hkey should be a previously obtained key handle or one of the string constants: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

w32RegDeleteValue

The w32RegDeleteValue subroutine deletes the value named valuename, which must be located under the key hkey.

Syntax:

call w32RegDeleteValue hkey, valuename

Example:

call w32RegDeleteValue whk, “WidgetMaximumSize”

Hkey should be a previously obtained key handle or one of the string constants: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

w32RegEnumKey

The w32RegEnumKey function returns the name of the subkey of hkey specified by index.

Syntax:

subkeyname = w32RegEnumKey ( hkey, index )

Example:

firstsubkey = w32RegEnumKey(“HKEY_LOCAL_MACHINE”, 0)

Hkey should be a previously obtained key handle or one of the string constants: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

Index ranges from 0 to w32RegQueryInfoKey(hkey, “NumSubKeys”)-1.

w32RegEnumValue

The w32RegEnumValue function returns the name of the value under hkey specified by index.

Syntax:

valuename = w32RegEnumValue ( hkey, index )

Example:

firstvalue = w32RegEnumValue(“HKEY_LOCAL_MACHINE”, 0)

Hkey should be a previously obtained key handle or one of the string constants: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

Index ranges from 0 to w32RegQueryInfoKey(hkey, “NumValues”)-1.

w32RegFlushKey

The w32RegFlushKey subroutine cause all changes in a key to be flushed immediately to disk. The use of this subroutine is normally not necessary and should only be used in very unusual circumstances.

Syntax:

call w32RegFlushKey hkey

Example:

call w32RegFlushKey hk

Hkey should be a previously obtained key handle or one of the string constants: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

w32RegGetKeySecDesc

The w32RegGetKeySecDesc function returns a hexadecimal string representing the self-relative security descriptor associated with key hkey.

Syntax:

secdesc = w32RegGetKeySecDesc ( hkey )

Example:

secdesc = w32RegGetKeySecDesc(“HKEY_LOCAL_MACHINE”)

Hkey should be a previously obtained key handle or one of the string constants: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

w32RegLoadKey

The w32RegLoadKey subroutine creates subkey subkeyname under the key hkey using the key hive stored in filename.

Syntax:

call w32RegLoadKey hkey, subkeyname, filename

Example:

call w32RegLoadKey hk, “Stuff”, “D:\keyhives\stuff”

Hkey should be a previously obtained key handle or one of the string constants: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

w32RegOpenKey

The w32RegOpenKey opens a subkey under a registry key. It returns a handle to the subkey opened.

Syntax:

hkeyRet = w32RegOpenKey ( hkey, subkeyname )

Example:

hk = w32RegOpenKey(“HKEY_LOCAL_MACHINE”,“Software\Microsoft\NewProduct”)

Hkey should be a previously obtained key handle or one of the string constants: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

w32RegQueryInfoKey

The w32RegQueryInfoKey returns the requested information about key hkey.

Syntax:

info = w32RegQueryInfoKey ( hkey, infoname )

Example:

nKeys = w32RegQueryInfoKey(hkey, “NumSubKeys”)

infoname

Value Returned

NumSubKeys

Number of subkeys under hkey.

MaxSubKeyName

Length of longest subkey name.

NumValues

Number of values under hkey.

MaxValueName

Length of longest value name.

MaxValueData

Size of largest data item stored in a value.

Hkey should be a previously obtained key handle or one of the string constants: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

w32RegQueryValue

The w32RegQueryValue function returns the data stored under valuename. If the data is of type REG_SZ or REG_EXPAND_SZ, a string is returned. If the data is of type REG_DWORD, a string representing that number is returned. All other data types return a hexadecimal string representation of the data.

Syntax:

value = w32RegQueryValue ( hkey, valuename )

Example:

wspeed = w32RegQueryValue(hk, “WidgetSpeed”)

Hkey should be a previously obtained key handle or one of the string constants: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

w32RegQueryValue

The w32RegQueryValue function returns the type of the data stored under valuename.

Syntax:

type = w32RegQueryValueType ( hkey, valuename )

Example:

type = w32RegQueryValueType(hk, “WidgetSpeed”)

Hkey should be a previously obtained key handle or one of the string constants: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

Type is returned as one of the following strings: REG_DWORD, REG_EXPAND_SZ, REG_SZ, REG_BINARY, REG_DWORD_BIG_ENDIAN, REG_LINK, REG_MULTI_SZ, REG_NONE, REG_RESOURCE_LIST, UNKNOWN.

w32RegRestoreKey

The w32RegRestoreKey subroutine overwrites hkey with information from the hive stored in filename.

Syntax:

call w32RegRestoreKey hkey, filename

Example:

call w32RegRestoreKey hk, “D:\keyhives\stuff”

Hkey should be a previously obtained key handle or one of the string constants: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

w32RegSaveKey

The w32RegSaveKey subroutine saves the information in hkey as a hive stored in filename.

Syntax:

call w32RegSaveKey hkey, filename

Example:

call w32RegSaveKey hk, “D:\keyhives\stuff”

Hkey should be a previously obtained key handle or one of the string constants: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

w32RegSetKeySecDesc

The w32RegSetKeySecDesc subroutine sets the security descriptor of key hkey.

Syntax:

call w32RegSetKeySecDesc hkey, secdesc

Example:

call w32RegSetKeySecDesc hk, “ff00...”

Hkey should be a previously obtained key handle or one of the string constants: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

SecDesc is a hexadecimal string representing a self-relative security descriptor. The easiest way to make one is to create a temporary key with REGEDT32.EXE, set its security, then use the w32RegGetKeySecDesc to obtain the security descriptor.

w32RegSetValue

The w32RegSetValue subroutine sets the value of valuename to data of type type.

Syntax:

call w32RegSetValue hkey, valuename, type, data

Example:

call w32RegSetValue hk, “BinaryUserInfo”, “REG_BINARY”, “ff003a”

Hkey should be a previously obtained key handle or one of the string constants: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

Type is one of the following strings: REG_DWORD, REG_EXPAND_SZ, REG_SZ, REG_BINARY, REG_DWORD_BIG_ENDIAN, REG_LINK, REG_MULTI_SZ, REG_NONE, REG_RESOURCE_LIST, UNKNOWN.

Data is a string if type is REG_SZ or REG_EXPAND_SZ. Data is a string of decimal digits if type is REG_DWORD. For all other types, data is a hexadecimal string representing the data.

w32RegUnLoadKey

The w32RegUnLoadKey subroutine unloads the subkey named by subkeyname.

Syntax:

call w32RegUnLoadKey hkey, subkeyname

Example:

call w32RegUnLoadKey hk, “Stuff”

Hkey should be a previously obtained key handle or one of the string constants: HKEY_LOCAL_MACHINE, HKEY_USERS.

Subkeyname must be the name of a subkey that was previously created with w32RegLoadKey.

Win32 Event Log Functions

The Win32 Event Log functions closely parallels the corresponding C functions found in the Win32 API. The descriptions below are fairly brief. Consult the Win32 SDK documentation for more detailed information.

The “W32FUNCS” subdirectory contains an example file: “eventlog.rexx” that uses the eventlog functions. See the “README.TXT” file in that subdirectory for more information on this example.

w32BackupEventLog

The w32BackupEventLog subroutine saves the event log opened on helog in the disk file specified by filename.

Syntax:

call w32BackupEventLog helog, filename

Example:

call w32BackupEventLog helog, “D:\keyhives\stuff”

w32ClearEventLog

The w32ClearEventLog subroutine clears the event log opened on helog. If the optional argument filename is provided, the eventlog will be saved to that file.

Syntax:

call w32ClearEventLog helog, [ filename ]

Example:

call w32ClearEventLog helog

w32CloseEventLog

The w32CloseEventLog subroutine frees any resources associated with the eventlog handle helog.

Syntax:

call w32CloseEventLog helog

Example:

call w32CloseEventLog helog

w32FindEventLogEntry

The w32FindEventLogEntry subroutine reads the eventlog entry specified by eventnum into a static buffer. This buffer is allocated on a per-process basis and any call to w32CloseEventLog or w32FindEventLogEntry on ANY HANDLE will invalidate the data from the previous call to w32FindEventLogEntry. Data from the static buffer is accessed by the w32GetEventCategory, w32GetEventData, w32GetEventID, w32GetEventNumStrings, w32GetEventString, w32GetEventTimeGenerated, w32GetEventTimeWritten and w32GetEventType functions.

Syntax:

call w32FindEventLogEntry helog, eventnum

Example:

call w32FindEventLogEntry helog, 1 /*Find first eventlog entry.*/

Eventnum ranges from 1 to w32GetNumberOfEventLogRecords(helog).

w32GetEventCategory

The w32GetEventCategory function returns the event category associated with event log entry found in the last call to w32FindEventLogEntry.

Syntax:

category = w32GetEventCategory ( )

Example:

category = w32GetEventCategory()

w32GetEventData

The w32GetEventData function returns a hexadecimal string representing the binary data associated with event log entry found in the last call to w32FindEventLogEntry.

Syntax:

data = w32GetEventData ( )

Example:

data = w32GetEventData()

w32GetEventID

The w32GetEventID function returns the event identifier associated with event log entry found in the last call to w32FindEventLogEntry.

Syntax:

id = w32GetEventID ( )

Example:

id = w32GetEventID()

w32GetEventNumStrings

The w32GetEventNumStrings function returns the number of strings associated with event log entry found in the last call to w32FindEventLogEntry.

Syntax:

nStrings = w32GetEventNumStrings ( )

Example:

ns = w32GetEventNumStrings()

w32GetEventString

The w32GetEventString function returns the string denoted by index associated with event log entry found in the last call to w32FindEventLogEntry.

Syntax:

string = w32GetEventString ( index )

Example:

str = w32GetEventString(1)

Index ranges from 1 to w32GetEventNumStrings().

w32GetEventTimeGenerated

The w32GetEventTimeGenerated function returns (for the event log entry found in the last call to w32FindEventLogEntry) the date the event was generated. The format of the date is that returned by the standard C function asctime.

Syntax:

date = w32GetEventTimeGenerated ( )

Example:

date = w32GetEventTimeGenerated()

w32GetEventTimeWritten

The w32GetEventTimeWritten function returns (for the event log entry found in the last call to w32FindEventLogEntry) the date the event was written. The format of the date is that returned by the standard C function asctime.

Syntax:

date = w32GetEventTimeWritten ( )

Example:

date = w32GetEventTimeWritten()

w32GetEventType

The w32GetEventType function returns the numeric type associated with event log entry found in the last call to w32FindEventLogEntry. Errors are type 1, Warnings are type 2, and Informational messages are type 4.

Syntax:

nStrings = w32GetEventType ( )

Example:

ns = w32GetEventType()

w32GetNumberOfEventLogRecords

The w32GetNumberOfEventLogRecords function returns the number of event log records in the event log opened on helog.

Syntax:

nRecords = w32GetNumberOfEventLogRecords ( helog )

Example:

nr = w32GetNumberOfEventLogRecords()

w32OpenBackupEventLog

The w32OpenBackupEventLog function returns a handle to the events in an eventlog backup file (created by w32BackupEventLog or w32ClearEventLog) stored on host hostname specified by filename. If hostname not specified, the event log is opened on the local host.

Syntax:

helog = w32OpenBackupEventLog ( [hostname], filename )

Example:

h = w32OpenBackupEventLog(, “C:\applog.evt”)

w32OpenEventLog

The w32OpenEventLog function returns a handle to the events in the sourcename eventlog stored on host hostname. If hostname not specified, the event log is opened on the local host.

Syntax:

helog = w32OpenEventLog ( [hostname], sourcename )

Example:

h = w32OpenEventLog(“\\mainserver”, “system”)

w32WriteEventLog

The w32WriteEventLog subroutine writes an event entry to the sourcename eventlog stored on host hostname. If hostname not specified, the event log written to is on the local host. Errors are type 1, Warnings are type 2, and Informational messages are type 4.

Syntax:

call w32WriteEventLog [ hostname ], sourcename, [ eventtype ],[ category ], [ eventid ], [ data ], [ string1 ... ]

Example:

call w32WriteEventLog , “My REXX Prog”, 2, , , , “Error message”

For eventtype, Errors are type 1, Warnings are type 2, and Informational messages are type 4.

Data is optional binary data to be put into the eventlog. It is specified as a hexadecimal string.

Eventtype defaults to 1 (Error).

Category defaults to 0.

EventID defaults to 0.

At least one of data or string1 must be present.

Known Limitations

Because Win32 raises process termination and process interrupt signals in a separate thread, the SIGNAL and CALL statements cannot be used with the HALT conditions.

Regina has been modified to treat attempts to use the HALT condition as a syntax error.

The implementation of the STREAM statement’s ‘C’ option is weak when used with the READABLE, EXECUTABLE or WRITEABLE commands:

· All regular files are considered executable.

· Only the older DOS-style read-only attribute is looked at to determine read-only. Windows NT security constraints imposed under NTFS are ignored.

Forcing a NOTREADY condition on a console "file" interacts with the underlying runtime stdio functions such that the file can never be reset. [This is a hard error to describe and one that you will probably never encounter. To understand it, Look in the "srccode\trip.w32" file: files.rexx. See the sections using "<stdout>" (tests 15 and 17) that are commented out.]

At the time of this writing, Windows 95 was still in beta. Only limited testing has been done under Windows 95.