LanFax Redirector

Application Programming Reference

Version 2.0



Table of  Contents
Table of  Contents	i
Introduction	1
About this Manual	1
Updates to this Manual	2
The CAS Standard	2
The spirit of the specification	3
Overview	6
Pointers	9
LanFax Redirector Extensions to CAS	13
Constants	13
Data Structures	18
Extended Standard Functions	19
Get Installed State and Workstation 
Version Number	19
Get Event or Server Date	20
Set Task or Server Date	20
Get Event or Server Time	21
Set Task or Server Time	21
Extended Functions -- Phonebook	22
Open Phonebook	22
Close Phonebook	22
Get Phonebook Status	23
Find First Entry in Phonebook	24
Find Next Entry in Phonebook	25
Add Entry to Phonebook	26
Delete Entry from Phonebook	27
Add Entry To Group	27
Delete Entry From Group	29
Get Entries of Group	29
Extended Functions -- Stream CAS	31
Find First Event	31
Find Next Event	33
Find Any Event	34
Extended Functions -- Misc	35
Forward A Received Event	35
Print An Event	35
Get Server Status	36
Get Board Status	36
Get Server Option	37
Set Server Option	39
Get/Set Board Status	40
Get/Set Retry Sequence	41
Set User Profile	42
Find User by Name	43
Find User by Mailbox	43
Kill Session	45
Kill Mailbox	46
Who-am-I	47
Authorize Transmission	48
Cancel/Delete a specified event	50
Register an ALCOM application	52
Alcom's Implementation of ASN.1	53
CAS Program Library for DOS	59
Constants and Data Structures	59
CAS Functions	60
CASGetInstalledState	60
CASSubmitTask	60
CASAbortCurrentEvent	62
CASFindFirst	63
CASFindNext	64
CASOpenFile	65
CASDeleteFile	67
CASDeleteAllFiles	68
CASGetEventDate	68
CASSetTaskDate	70
CASGetEventTime	71
CASSetTaskTime	72
CASGetExternalData	73
CASAutoReceiveState	74
CASGetCurrentEventStatus	75
CASGetQueueStatus	76
CASGetHardwareStatus	77
CASRunDiagnostics	78
CASMoveReceivedFile	79
CASSubmitSingleFile	81
CASUnloadResidentManager	82
Extensions to CAS Functions	83
SCASFindFirst	83
SCASFindNext	85
SCASFind	86
SCASForward	87
SCASPrint	88
SCASGetServerStatus	89
SCASGetBoardStatus	89
SCASGetServerOption	91
SCASSetServerOption	92
SCASSetBoardStatus	93
SCASSetRetrySequence	94
SCASSetUserProfile	95
SCASFindUserByName	95
SCASFindUserByMbox	97
SCASKillSession	98
SCASKillMailbox	98
SCASWhoAmI	100
SCASAuthorize	100
SCASCancelEvent	102
SCASRegisterUI	102
Phonebook Functions	104
SCASOpenPhonebook	104
SCASClosePhonebook	105
SCASGetPhonebookStatus	105
SCASFindFirstPhonebook	107
SCASFindNextPhonebook	107
SCASAddPhonebookEntry	109
SCASDeletePhonebookEntry	109
SCASAddPhonebookGroupEntry	111
SCASDeletePhonebookGroupEntry	111
SCASGetPhonebookGroupEntry	113
CAS DLL for Windows 2.x and 3.0	115
Target Audience and Requirements	115
Introduction	115
CAS DLL Architecture	116
Dynamic Link Libraries	116
Import Library	117
Include File	117
Calling Conventions	118
Dynamic Linking	118
Explicit Run-Time Linking	118
CAS DLL Functions	119
Function 0:  CASGetInstalledState	120
Function 1:  CASSubmitTask	121
Function 2:  CASAbortCurrent EVENT	121
Function 5:  CASFindFirst	122
Function 6:  CASFindNet	123
Function 7:  CASOpenFile	124
Function 8:  CASDeleteFile	125
Function 9:  CASDeleteAll	125
Function 10:  CASGetEventDate	127
Function 11:  CASSETTaskDate	127
Function 12:  CASGetEventTime	129
Function 13:  CASSetTaskTime	129
Function 14:  CASGetExtDataBlock	131
Function 15:  CASAutoReceiveState	131
Function 16:  CASGetCurEventStatus	132
Function 17:  CASGetQueueStatus	132
Function 18:  CASGetHWStatus	134
Function 19:  CASRunDiags	134
Function 20:  CASMoveFile	135
Function 21:  CASSubmit1File	135
Function 129:  CASSetMultiPlex	136
Function 130:  CASSingleUser	136
Function 131:  CASGetMultiPlex	137
Function 132:  CASCall	138
Function 144:  PCASOpenPB	140
Function 145:  PCASClosePB	140
Function 146:  PCASGetStat	141
Function 147:  PCASFindFirst	142
Function 148:  PCASFindNext	143
Function 149:  PCASAddEntry	144
Function 150:  PCASDeletePBEntry	145
Function 151:  PCASAddEntry2Group	145
Function 152:  
PCASDeleteEntryFromGroup	146
Function 153:  PCASGetEntriesOfGroup	147
Function 160:  SCASFindFirst	148
Function 161:  SCASFindNext	150
Function 162:  SCASFind	151
Function 163:  SCASForward	152
Function 164:  CASPrintEvent	153
Function 165:  CASGetServerStatus	154
Function 166:  CASGetBoardStatus	154
Function 167:  CASGetSrvOption	155
Function 168:  CASSetSrvOption	157
Function 169:  CASGetSetBrdStatus	159
Function 170:  CASGetSetRetrySeq	160
Function 171:  CASSetUserProfile	161
Function 172:  CASFindUserName	162
Function 173:  CASFindUserMbox	163
Function 174:  CASKillSession	164
Function 175:  CASKillMbox	165
Function 176:  CASWhoAmI	166
Function 177:  CASAutTransmission	167
Function 178:  CASCancelEvent	168
Function 179:  CASRegAlcomApp	170
Function 200:  CASOpen	171
Function 201:  CASClose	172
Function 202:  CASResetFindNext	172
Data Structures	174
Appendix A:  Configuration	181
Overview	181
Options	183
Enable printer - prt	183
Set Printer Port - prp	183
Set printer device/file - prf	183
Set database locations - dbu, dbp, 
dba	184
Board Scan Frequency - bsc	184
Paradox Network Operating System - 
nos	184
Paradox Sort Order - prs	185
Default  Send/Receive Board Rights - 
dsb, drb	186
Server Name - svn	187
Set Incoming Xfers/Faxes 
Public/Private - xpf, fpf	188
Require Users to be Registered - reg	188
Set Debug Level - deb	188
Number of Buffers - buf	189
Event Cache buffer - cac	189
Database Cache - dbc	189
Paradox NET file Location - pxn	190
HP PCL Font Path - hpp	190
HP PCL Soft Font Path - sft	190
Paradox Maximum Table Size - pxm	191
Paradox Maximum Record Locks - pxr	191
Archival volume path	191
Automatic Print of Incoming/Outgoing 
Faxes - prs	191
Notify Administrators - adn, adm	191
Notify Users - usn	192
Default Administrator Rights - dea	192
Default User Rights - deu	192
Retry Times - ret	193
Retry Reasons - rtr	193
Prefix Code for Phone Numbers - pre	194
Postfix Code for Phone Numbers - pos	194
Override Character - ove	194
Default Country Code - cco	194
Default Area Code - aco	194
Default visibility for Phonebook - 
vis	195
Escape Country Code - ecc	195
Escape Area Code - eac	195
Administrator Name for Notification - 
adm	196
Convert ASCII to PCX Too - cas	196
Archive Type - art	196
Clear Log By Date Automatically - cld	196
Clear Log by Entries Automatically - 
cle	196
Enable International Phone Number 
Handling - iph	197
Withhold Last Session - wls	197
Cache Databases - cau, cap, caa	198
Multiplex Numbers of Fax Boards - brd	198
Board Rights bits - brb	199
Paradox Database Passwords - prp	199
Transport Layer Commands - cmd	200
PCL Conversion Command Line 
Parameters - cdc	201
Change Converted Name - nch	202
Use EMS/XMS Memory - mem	202
Specify Memory for VROOMM - vrm	203
Set Default Logo File - lgo	203
Black and White Mode - bnw	203
Congestion Level - con	203
Block-Time - bti	204
Print Priority - ppi	205
Library Path - lib	205
Number of File Handles - fil	206
Phonebook Number Separators - pbs	207
Download Path for Administrator Users 
- dlp	207
Page Headers - phe	208
Accepted Tokenizer Errors - tok	209
Appendix B:  Task File	211
Adding Users	211
Delayed Shutdown	212
Clear An Event	212
Add Names to Phonebook	212
Appendix C:  Database Linkage	215
USERS	216
AUDIT	216
PHONE	217
GROUP	217



Introduction
About this Manual
This manual is a guide for programmers who 
are writing CAS-compatible applications to 
be used with Alcom's LanFax Redirector fax 
server.  This manual describes:
	- Alcom's extensions to CAS 
(specification)
	- ASN.1 notation and tags used in 
packets for managing the phonebook
	- C++ language library for DOS 
applications
	- DLL module for Windows applications
Included with this package as an ASCII 
file is 
	- the original CAS specification by 
Intel and DCA
which fully describes CAS.  This file is 
located on the Application Programming 
Tools disk.  It is also available from 
Intel or from Alcom's bulletin board 
system.
Programmers may need to manipulate 
specifics of the configuration of the fax 
server.  In an Appendix, the LANFAX.CFG 
configuration file (normally manipulated 
and maintained with the SETUP program) is 
described in detail.  The Task file (the 
fax server's batch facility) is also 
discussed.  In addition, a precise 
description of Paradox field linkages is 
provided.
Updates to this Manual
This manual, because of its technical 
nature is more susceptible than most to 
obsolescence.  Included on the Application 
Programming Tools disk is a collection of 
ASCII files which contain the most up-to-
date versions of this information at the 
time your disks were created.  The most 
recent versions can also be downloaded 
from Alcom's bulletin board system.  The 
READ.ME file explains what the files 
contain.
The CAS Standard
The CAS standard specifies how to manage a 
fax card via multiplex interrupt calls. To 
access CAS, you simply load certain values 
to CPU registers and then issue a software 
interrupt.  To access the LanFax 
Redirector, the workstations must load a 
TSR which traps such interrupts and 
forwards them to the server.  In this 
manner, stand-alone CAS applications can 
instantly be networked, transparently to 
the user.
The CAS standard provides an effective way 
of creating applications that can monitor 
the status of a fax transmission on a 
constant basis. An application can, for 
example, display the status of a fax as it 
is first waiting, then dialing, then 
sending page by page etc. The application 
can even show when the receiving machine 
identifies its CSID and provide a last 
opportunity for the user to cancel the 
event.
The LanFax Redirector server provides the 
same capabilities, over the network.  In 
fact, Alcom is committed to comply with 
standards and our implementation of CAS 
follows meticulously the original 
specification by Intel and DCA.  However, 
to remedy some of the shortcomings of CAS 
and to speed up some operations, Alcom has 
enhanced and extended CAS.   Standard CAS 
calls are still guaranteed to work.  
However if an application uses Alcom's 
extensions, many additional functions 
become available, network traffic is 
minimized and CAS becomes more efficient.
This manual assumes you are familiar with 
the CAS standard and programming. This 
text is not intended as a primer to 
either, although the CAS specification can 
act as a primer to itself.  Programming 
knowledge is a prerequisite to 
understanding this manual.
The spirit of the specification
There are a number of points to be watch 
for when working with a networked CAS 
application.  CAS was not originally 
designed with network applications in mind 
and consequently, it is not naturally 
optimized for network overheads.
 - Be careful of excessive network 
traffic.  Read only the portions of data 
in memory you need. Read the attachments 
page at a time, avoid downloading and then 
displaying. Read lists a visible portion 
at a time, not the whole thing (you 
wouldn't have the memory anyway).
- Do error checking.  Since this is a 
client-server system, there are 
potentially other users active also. 
Someone who has rights over you could 
delete a file right from under you. Always 
check properly for error returns.
- Use the Stream CAS functions; they have 
an 8:1 performance improvement and an 1:8 
improvement in traffic over standard CAS.
- Set the server database sorting order 
properly; the server has an extensive 
database engine that knows how to sort.  
Use that instead of trying to sort entries 
yourself. Don't assume you know the 
sorting order, a new sorting order may be 
set later, and even today there's no way 
to know the sorting order (from the 
applications).
 - Don't ever keep information regarding 
events. Applications that keep an internal 
table of events are bound for trouble. The 
list of events can change any moment 
without warning, and consequently any 
table you might be able to construct will 
be obsolete the moment it's ready.
- Don't assume anything; do not assume 
that you can figure out the way the server 
allocates event numbers or phonebook ID's.
- Don't even think you can keep a whole 
list in memory. The number of events can 
today be up to 2048, tomorrow it could be 
20480. Today the number of phonebook 
entries can be 32000, tomorrow it could be 
2 billion. Today the number of mailboxes 
can be 8000, tomorrow it could be 2 
billion. Use virtual picklists, don't keep 
static arrays.
- Don't rely on sequences; Phonebook 
indexes are just a convenient way of 
moving through the phonebook and using 
them to recall a particular entry is a 
problem. That's why the IDs are there.
- Don't think you have the submission 
sequence figured out (waiting->dialing-
>sending->complete) since frequently the 
server may do something different.  Just 
ask the server what the status of an event 
is and you're safe.
- Don't store the user profile locally; 
the administrator may change user 
privileges, and all of a sudden (even in 
the middle of a session) the user may be 
able to do something he/she wasn't able to 
do five minutes ago.
- Don't be afraid of the ASN.1 structured 
phonebook.  At first it might look 
intimidating, and for some reason ASN.1 
has gotten a bit of a reputation for being 
complex, but after working with it for a 
short while, it's actually easier and more 
flexible than any other data abstraction 
syntax.
Of course, if you do not wish to tackle 
ASN.1, then just use the readily available 
calls to assemble/disassemble ASN.1 
packets to/from regular structures.
Overview
Alcom has extended the CAS specification's 
22 function calls by an additional 30 
functions:
	10	Calls for phonebook access 
(PCAS)
 	 3	StreamLined CAS calls (SCAS)
	17	Extended CAS calls (ECAS)
Alcom has also enhanced 5 original CAS 
calls.
The additions have been done so that the 
function numbers span between 0x90..0x99 
and 0xA0..0xB3.
The enhancements have been done so that 
they affect regular CAS in no detectable 
fashion.  Some examples:

0x0C	Get Event Time [enhanced]
Usually when you get an event time (or 
date), you use an event number, found with 
either FindFirst or FindNextCAS calls.
Alcom Redirector never gives out one 
"magical" event number, 32767, which "is 
the server itself".
If you do a Get Event Time with event 
number 32767,  you get the server time. 
The same can be done to date and the 
equivalent Set Time/Date functions can be 
used in the same fashion to set the server 
time/date.
This is a safe extension, because the 
server itself controls what event numbers 
it gives out, and since it will never give 
out an event number 32767, then nobody 
should be setting/getting the time/date of 
that event either.

0xA0	StreamCAS find first event [extended]
The majority of applications want to 
browse through events in a particular 
queue. This is usually done with a pair of 
CAS Find First/Next calls.
Because these calls return only the event 
number, all applications must open the 
task control file (another CAS call), do 
some seeks (DOS calls), do some reads (DOS 
calls) and eventually close the file 
(another DOS call). So all together 
reading queues generates quite a bit of 
activity, especially if done through the 
network.
With Alcom's Stream CAS you can do the 
same Find First/Next but you set up a 
buffer of 303 bytes (the size of the Task 
Control File (TCF) minus the logo file 
name) and once an event is found, the 
buffer is immediately filled with all the 
relevant information about the event -- 
all in one call. The savings on a network 
is about 1:8.

0xA3	Forward an event [extended]
Quite frequently it is necessary to 
forward an event, either to another person 
on the LAN (routing) or to a fax machine 
(outside transmission).
In many cases, the attachments are to stay 
the same, but a new cover page is 
required.
With regular CAS you would have to:
1)	Download all the attachments
2)	Reconstruct the TCF and the FTR's
3)	Submit the job as a new item
With Alcom's extended CAS, you just create 
the TCF, no FTR portions are required, 
then just submit it as it were a "cover 
page only" but with two exceptions:
1)	Set BX to contain the event that is 
to be forwarded
2)	Use the 0xA3 (forward) instead of 
0x01 (submit)
The event will be on its way with exactly 
one packet moving on the network. 
Forwarding messages is thus much more 
efficient than using standard CAS.

0xA4	Print an event [extended]
Since faxes (especially received ones) 
need to be printed quite frequently and 
since the Redirector server is a 
multitasking program, we have added the 
printing capability to it.
The Alcom LanFax Redirector server can 
print all rasterized events in a queued 
fashion, as time and traffic allows.  
Printing an event is trivial, after the 
event number is found.  Simply perform a 
0xA4 (print) call, and the server will 
queue it for printing.
It is also possible to query the print 
status of an event and to cancel the 
printing of an event.
NOTE: the server may also have automatic 
printing on, which may cause multiple 
copies to be printed if applications start 
printing events.  Also since one event may 
be visible to more than one 
application/user multiple copies may be 
caused by applications randomly issuing 
print calls.  If automatic printing is 
desired, let the server do it.
Pointers
How do I get the server name?
First get the server status.  This will 
tell you the maximum number of maiboxes 
supported.  Add one to that maximum and 
using that mailbox number, get the user 
profile.  The server is a special user 
whose mailbox number is one more than the 
maximum number of allowed mailboxes.  For 
example, if you have a system which allows 
8000 mailboxes, ask for the user profile 
of mailbox 8001 and you will be given 
server information.
LanFax Redirector is heavily object 
oriented and the server itself is just one 
user among others, albeit a special one.

How do I add 10,000 entries into the 
phonebook?
Using PB2SRV or ASC2SRV from a workstation 
uses CAS calls.  This may be the simplest 
route, although not necessarily the most 
efficient.  This will require heavy 
network access and depending on the speed 
of the workstation and the server's load, 
this can take quite a few minutes.
Another option is to take the server down 
and import the 10,000 names into the 
phonebook using Paradox.
Yet another option is to use the server's 
taskfile LANFAX.TSK which can be set so 
that the server performs a batch job to 
update a whole bunch of phone numbers.

How can I find out what's wrong with my 
new application?
Just press D  on the server keyboard to 
select the Debug command. The server will 
start displaying all kinds of diagnostic 
and debug information about incoming CAS 
requests and its responses.
Pressing D repeatedly moves through three 
levels of Debug:
	0	No debug, regular running mode
	1	Debug all regular operations
	2	Debug every single CAS call that 
comes in
Notice that levels 1 and 2 both contribute 
an enormous amount of screen activity and 
thus slow down the server noticeably.
If you are really in a pinch, contact 
Alcom.  We have debugging versions of 
WKS_???.EXE, LANFAX?.COM and SRV_???.EXE 
programs which will give even more 
information.

How can I do a virtual picklist on 
Microsoft Windows?
We have a DLL that can perform a virtual 
picklist.  Call Alcom Product Support and 
we'll get it to you.


LanFax Redirector Extensions to CAS
Constants
// For Tags, primitives, etc check file ASN1.H

//
// Phonebook Names
//
#define pbnAll	  	 "ALL"
#define pbnPhones  	"PHONES"
#define pbnPersons 	"PERSONS"
#define pbnGroups 	 "GROUPS"
//
// RAM type values
//
enum RamTypes {
    rtNormal = 0,		// normal memory
    rtEMS,		// expanded memory
    rtXMS,		// extended memory via XMS
    rtEXT,		// extended memory via BIOS
    rtNone,		// no memory
};
//
// Server Option Bits
//
enum ServerOptionBits {
    soArchival   = 0x0001,
    soPrinting   = 0x0002,
    soRegistered   = 0x0004,
    soPCL5  = 0x0008,
    soFileCAS   = 0x0010,
    soPublicFaxes  = 0x0020,
    soPublicBFTs   = 0x0040,
    soAutoInPrint  = 0x0080,   	 // Automatic printing of incoming on?
    soAutoOutPrint = 0x0100,    	// Automatic printing of outgoing on?
    soBilling      = 0x0200,    	// Billing enforced?
};
//
// Rights of a user
//
#define ADM_ROUTER 	0x0001 	 // Router Rights
#define ADM_FIND  	0x0002  	// Find first/next entry
#define ADM_DELETE 	0x0004  	// Delete a file
#define ADM_DELALL 	0x0008  	// Delete all files in a queue
#define ADM_CONFIG 	0x0010 	 // Configuration privilege
#define ADM_CANCEL 	0x0020  	// Right to cancel any event
#define ADM_PB      	0x0040  	// PhoneBook admin rights
#define ADM_RUSH    	0x0080  	// Does the user have rights for rush jobs
#define ADM_9    	0x0100
#define ADM_10    	0x0200
#define ADM_11   	0x0400
#define ADM_12   	0x0800
#define ADM_13   	0x1000
#define ADM_14   	0x2000
#define ADM_15   	0x4000
#define ADM_NOENTRY  	0x8000  // Sign on refused for this user
//
// Board Capabilities
//
#define bcCanSend 's'	 	// Board is used for send only
#define bcCanReceive  'r' 		// Board is used for receive only
#define bcCanSendAndReceive 'b' 	// Board is used bidirectionally
#define bcNotAvailable  'n' 	// Board not available to user or server
#define bcNonExisting  'i' 		// Board does not exist [hw-wise]
//
// Board Status values
//
#define bsSending   's'        	 // Board sending
#define bsReceiving 'r'        	 // Board receiving
#define bsIdle      'i'        		 // Board idle
#define bsAbort     'a'         	// Board aborting event
#define bsDialing   'd'         	// Board dialing
#define bsWaiting   'w'        	// Event waiting on board [very rare]
#define bsError     'e'        		// Board or event @ board in error
#define bsWhoa      '?'         	// Undefined board status
#define bsProblem   'p'         	// A stuck item
//
// Phonebook Search Directions
//
enum PhonebookSearchDirections {
    pbsdForward = 0,
    pbsdBackward
};
//
// Stream CAS Queues
//
enum StreamCasQueues {
    scqTransmit = 0,
    scqReceive,
    scqLog
};
//
// Standard CAS Queues
//
enum StandardCasQueues {
    ncqTask = 0,
    ncqReceive,
    ncqLog
};
//
// Server Option Commands
//
enum ServerOptionCommands {
    socPrinterType = 0,
    socPrintingStatus,
    socSecurity,
    socConversion,
    socRegistration,
    socClearLogByDays,
    socClearLogByEvents,
    socArchivalStatus
};
//
// Server Printer Types
//
enum ServerPrinterTypes {
    sptLaserJetII = 0,
    sptLaserJetIIP,
    sptLaserJetIII
};
//
// Server Printing Status
//
enum ServerPrintingStatus {
    spsPrintNone = 0,
    spsPrintIncoming,
    spsPrintOutgoing,
    spsPrintBoth
};
//
// Server Incoming Security
//
enum ServerIncomingSecurity {
    sisPublic = 0,
    sisPrivate
};
//
// Server Conversion Status
//
enum ServerConversionStatus {
    scsNoConversion = 0,
    scsConvertToPCL
};
//
// Server Registration Status
//
enum ServerRegistrationStatus {
    srsNoRegistration = 0,
    srsRegistrationReqd
};
//
// Server Archival Status
//
enum ServerArchivalStatus {
    sasArchiveNone = 0,
    sasArchiveIncoming,
    sasArchiveOutgoing,
    sasArchiveBoth
};
//
// Board Status Commands
//
enum BoardStatusCommands {
    bscDeactivateBoard = 0,
    bscSendOnly,
    bscReceiveOnly,
    bscBoth
};


Data Structures
//
// ServerStatus -- returned by GetServerStatus call
//
struct ServerStatus {
    char RevNum[6];	// server version "3.0"
    dword UpTime;	// # of seconds since startup
    byte IdleBoards;	// # of idle boards
    byte TotalBoards;	// total # of boards
    word IPSendEvents;	// # of send events in process
    word RecEvents;	// # of received events
    word SendEvents;	// # of send events
    word CurrUsers;	// # of users logged in
    word TotalSrvUsers; // # of users available [server]
    word TotalNetUsers; // # of users available [network]
    word Mailboxes;	// # of mailboxes in use
    word TotalMailboxes;// total # of mailboxes
    dword DiskSpace;	// # of bytes available at server disk
    dword DiskSize;	// # of bytes at server
    dword ArchSpace;	// # of bytes available at archive site
    dword ArchSize;	// # of bytes at archive site
    dword RamConv;	// # of bytes conventional memory
    dword RamExt;	// # of bytes external memory available
    dword RamTotalExt;	// # of bytes external memory
    byte RamType;	// type of external memory
    word Options;	// server options
    byte ParadoxNOS;	// NOS for Paradox
    word TotalEvents;   // Total # of events available
    word Events;        // # of events in use
};
//
// BoardStatus -- two of these are returned by GetBoardStatus call
//
struct BoardStatus {
    char CapBoard;	// board capabilities
    char StatBoard;	// board status
    char SenderName[80];
    char DestName[80];
    char PhoneNum[50];
    word ConnectionTime;
};


Extended Standard Functions
Get Installed State and Workstation Version 
Number
Input:
	AH = multiplex #
	AL = 00h
optionally:
	BX = magic value #1 = 4143h = 'CA'
	CX = magic value #2 = 5253h = 'SR'
	DX = query type:
		4B4Fh = 'OK' = report workstation state in AX
		4E4Fh = 'ON' = switch workstation ON
		464Fh = 'OF' = switch workstation OFF
Output:
	AL = installed status:
		00h = not installed
		01h = not installed, not ok to install
		FFh = installed

      or if upon entry BX = 'CA', CX = 'SR', and DX = 'OK':

	AX = workstation state:
		4B4Fh = 'OK' = workstation is ON (activated)
		464Fh = 'OF' = workstation is OFF (deactivated)
	BL = workstation major version #
	BH = workstation minor version #

      or if upon entry BX = 'CA', CX = 'SR', and DX = 'ON' or 'OF':

	AX = workstation state:
		4E4Fh = 'ON' = workstation switched ON (activated)
		464Fh = 'OF' = workstation switched OFF (deactivated)
		xx01h = state switch failed


Get Event or Server Date
Input:
	AH = multiplex #
	AL = 0Ah
	BX = event handle, or 7FFFh = get server date
	DL = queue:
		0 = task queue
		1 = receive queue
		2 = log queue
Output:
	AX = 0 if successful or negative error code
	CX = year (1980-2099)
	DH = month (1-12)
	DL = day (1-31)


Set Task or Server Date
Input:
	AH = multiplex #
	AL = 0Bh
	BX = event handle, or 7FFFh = set server date
	CX = year (1980-2099)
        	DH = month (1-12)
        	DL = day (1-31)
Output:
	AX = 0 if successful or negative error code

Notes:
	The server-specific function (BX = 
7FFFh) requires server administrator 
privileges


Get Event or Server Time
Input:
	AH = multiplex #
	AL = 0Ch
	BX = event handle, or 7FFFh = get server time
	DL = queue:
		0 = task queue
		1 = receive queue
		2 = log queue
Output:
	AX = 0 if successful or negative error code
	CH = hour (0-23)
	CL = minutes (0-59)
	DH = seconds (0-59)
	DL = 0


Set Task or Server Time
Input:
	AH = multiplex #
	AL = 0Ch
	BX = event handle, or 7FFFh = set server time
	CH = hour (0-23)
        	CL = minutes (0-59)
        	DH = seconds (0-59)
Output:
	AX = 0 if successful or negative error code

Notes:
	The server-specific function (BX = 
7FFFh) requires server administrator 
privileges


Extended Functions -- Phonebook
Open Phonebook
Input:
	AH = multiplex #
	AL = 90h
	DS:DX = pointer to a Transfer record of the OpenPhonebook type
Output:
	AX = 0 if successful or negative error code
	BX = phonebook handle
	CX = # of entries in the phonebook

Note:   TR is filled with PBC_Defaults and 
thus all applicable default fields
Errors:
        PBE_NoSessions = No sessions 
available


Close Phonebook
Input:
	AH = multiplex #
	AL = 91h
	BX = phonebook handle
Output:
	AX = 0 if successful or negative error code
Errors:
        No errors


Get Phonebook Status
Input:
	AH = multiplex #
	AL = 92h
Output:
	AX = 0 if successful or negative error code
	BL = # of users currently accessing the phonebook
	BH = max # of concurrent phonebook users
	CX = # of entries in the phonebook
	DX = # of changes made into the phonebook since server startup

Errors:
        No errors


Find First Entry in Phonebook
Input:
	AH = multiplex #
	AL = 93h
	BX = phonebook handle
	DS:DX = pointer to a buffer containing a Transfer Record of
		the SearchPattern type; the buffer must be large enough
		to hold any found entry
Output:
        	AX = 0 if successful or negative error code

Errors:
        PBE_AccessDenied = Match found, 
but unavailable
        PBE_SearchFailed = Database search 
couldn't find exact match
        PBE_UnknownSearch = Search type 
not recognized
Note:
        If searching with Index and trying 
to find the last item, specify 0xFFFF.   
If searching with Index and trying to find 
the first item,  specify 0x0001.


Find Next Entry in Phonebook
Input:
	AH = multiplex #
	AL = 94h
	BX = phonebook handle
	CL = search direction:
		0 = search forward
		1 = search backward
		2-255 = reserved
        	DS:DX = pointer to a buffer large enough to hold a Transfer
                	Record for the found name. Find next is always the
                	next or previous available based on Index.
Output:
        	AX = 0 if successful or negative error code

Errors:
        PBE_LastFirst = Previous entry was 
alread last/first


Add Entry to Phonebook
Input:
	AH = multiplex #
	AL = 95h
	BX = phonebook handle
	DS:DX = pointer to a Transfer Record of the Person type
Output:
	AX = 0 if successful or negative error code
        	BX = Identifier of the newly added entry in the phonebook

Errors:
        PBE_IllegalMode = Only admins can 
add public entries
        PBE_DuplicateEntry = Duplicate 
entry was attempted
        PBE_DBerror = Database failed to 
add entry
        PBE_IllegalReplace = Bad replace, 
see notes

Notes:
        If Transfer record contains ID, 
and the ID already exists, this will be 
considered a UPDATE instead of ADD, and 
thus PBE_DuplicateEntry will not happen.  
If Transfer record contains ID, and the ID 
does not exist, this will be considered a 
PBE_IllegalReplace.


Delete Entry from Phonebook
Input:
	AH = multiplex #
	AL = 96h
	BX = phonebook handle
	DX = identifier of the entry to delete
Output:
	AX = 0 if successful or negative error code

Errors:
        PBE_DBerror = Entry found, but 
database failed to delete
        PBE_AccessDenied = Entry found, 
but access denied
        PBE_SearchFailed = Entry not found


Add Entry To Group
Input:
	AH = multiplex #
	AL = 97h
	CX = identifier of the group
	DX = identifier of the entry to add
Output:
	AX = 0 if successful or negative error code

Errors:
        PBE_SearchFailed = Group 
identifier not found
        PBE_NotGroup = Entry by identifier 
not a group
        PBE_DBerror = Database failed to 
add entry to group


Delete Entry From Group
Input:
	AH = multiplex #
	AL = 98h
	CX = identifier of the group
	DX = identifier of the entry to delete
Output:
	AX = 0 if successful or negative error code

Errors:
        PBE_SearchFailed = Group not found
        PBE_NotInGroup = Entry not found 
in Group, Group was found
        PBE_NotGroup = Identifier was not 
a group


Get Entries of Group
Input:
	AH = multiplex #
       	AL = 99h
	CX = identifier of the group
        	BX = "page#", 0=first 256, 1=second, etc.
        	DS:DX = pointer to buffer large enough to hold at least 256 
		identifiers (size 512 bytes)
Output:
        	AX = 0 if successful, 1 if more to come or negative error code
        	CX = number of entries in buffer
Errors:
        PBE_SearchFailed = Group not found
        PBE_DBerror = Database failed to 
access ID list
        PBE_NotGroup = Identifier didn't 
point to a group


Extended Functions -- Stream CAS
Find First Event
Input:
	AH = multiplex #
	AL = A0h
        	BX = 0 if just regular find first or last.  Other than 0 attempt to 
position based on the Event # just like Find Any Event [A2h] would do.
	CL = queue to search (server queues, NOT normal CAS):
		0 = transmit queue
		1 = receive queue
		2 = log queue
		3-255 = reserved
	CH = direction:
		0 = search forward
		1 = search backward
		2-255 = reserved
	DS:DX = pointer to a 303-byte buffer; the buffer is filled
		with the event's TCF minus the logo file path and
		the cover page text
Output:
	AX = 0 if successful or a negative error code
	BX = event handle
	CH = actual CAS queue in which this event can be found:
		0 = task queue
		1 = receive queue
		2 = log queue
      		0xff = current event
        	CL = extended status
                	0 = event has no pending operations
                	1 = event will be printed
                	2 = event is printing

Note:
        If BX was not zero and yet, the 
event# could not be found, then an error 
is not returned, but BX is rather assumed 
to be meant to be 0.  For consistency 
check if BX is equal to what was supplied.  
If searching forward, the first available 
event will be given.  If searching 
backwad, the last available event will be 
given.


Find Next Event
Input:
	AH = multiplex #
	AL = A1h
	CL = queue to search (server queues, NOT normal CAS):
		0 = transmit queue
		1 = receive queue
		2 = log queue
		3-255 = reserved
	DS:DX = pointer to a 303-byte buffer; the buffer is filled
		with the event's TCF minus the logo file path and
		cover page text
Output:
	AX = 0 if successful or a negative error code
	BX = event handle
	CH = actual CAS queue in which this event can be found:
		0 = task queue
		1 = receive queue
		2 = log queue
                	0xff = current event
        	CL = extended status
                	0 = event has no pending operations
                	1 = event will be printed
                	2 = event is printing


Find Any Event
Input:
	AH = multiplex #
	AL = A2h
	BX = handle of event to find
	DS:DX = pointer to a 303-byte buffer; the buffer is filled
		with the event's TCF minus the logo file path and
		cover page text
Output:
	AX = 0 if successful or a negative error code
	BX = event handle
	CH = actual CAS queue in which this event can be found:
		0 = task queue
		1 = receive queue
		2 = log queue
                	0xff = current event
        	CL = extended status
                	0 = event has no pending operations
                	1 = event will be printed
                	2 = event is printing


Extended Functions -- Misc
Forward A Received Event
Input:
	AH = multiplex #
	AL = A3h
	BX = handle of event to forward
	DS:DX = pointer to the filename of the TCF file; the TCF must
		contain the new destination information
Output:
	AX = 0 if successful or a negative error code
	BX = event handle of new event


Print An Event
Input:
	AH = multiplex #
	AL = A4h
	BX = handle of event to print
        	CL = operation:
               	0 = Get print status of event
                	1 = Print this event
                	2 = Don't print this event
Output:
        	AX = negative error code or:
                	0 = This event will not be printed
                	1 = Event is to be printed
                	2 = Event is printing at the moment


Get Server Status
Input:
	AH = multiplex #
	AL = A5h
	DS:DX = pointer to a 57-byte buffer; the buffer is filled
		with the ServerStatus structure
Output:
	AX = 0 if successful or negative error code



Get Board Status
Input:
	AH = multiplex #
	AL = A6h
	CX = bank #, 0-7; 1 bank = 2 boards
	DS:DX = pointer to a 2*214-byte buffer; the buffer is filled
		with two structures of the BoardStatus type
Output:
	AX = 0 if successful or negative error code
	CX = # of boards available


Get Server Option
Input:
	AH = multiplex #
	AL = A7h
	CL = option #:
		0 = printer type
		1 = printing status
		2 = security of incoming data
		3 = conversion status
		4 = registration status
		5 = clear log by days automatically
		6 = clear log by events automatically
		7 = archival status
		8-255 = reserved
Output:
	AX = 0 if successful or negative error code
	DX = option value
	printer type:
                        	1 = LaserJet II, 300 dpi
                        	2 = LasetJet II, 100 dpi
                        	3 = LaserJet IIP, 300 dpi
                        	4 = LaserJet IIP, 100 dpi
                        	5 = LaserJet III, 300 dpi
                        	6 = LaserJet III, 100 dpi
                        	7-65535 = reserved
	printing status:
		0 = print nothing
                        	1 = print outgoing only
                       	2 = print incoming only
		3 = print both incoming and outgoing
		4-65535 = reserved
	security of incoming data:
                        	0 = all private
                       	1 = Faxes public
                        	2 = XFR's public
                        	3 = Faxes and XFR's public
                        	4-65535 = reserved
	conversion status:
		0 = no conversion
		1 = convert ASCII to PCL
		2-65535 = reserved
	registration status:
		0 = no registration required
		1 = registration required
		2-65535 = reserved
	clear log by DX days automatically
                        	0 = do not clear by days
                        	1..65535 = clear entry after 1..65535 days
	clear log by DX events automatically
                        	0 = do not clear by events
                        	1..65535 = clear after 1..65535 events in system
	archival status:
		0 = archive none
                        	1 = archive outgoing
                        	2 = archive incoming
		3 = archive both incoming and outgoing
		4-65535 = reserved
                	8-255 = reserved


Set Server Option
Input:
	AH = multiplex #
	AL = A8h
	CL = option #:
	0 = printer type, DX =
                        	1 = LaserJet II, 300 dpi
                        	2 = LasetJet II, 100 dpi
                        	3 = LaserJet IIP, 300 dpi
                        	4 = LaserJet IIP, 100 dpi
                        	5 = LaserJet III, 300 dpi
                        	6 = LaserJet III, 100 dpi
                        	7-65535 = reserved
	1 = printing status, DX =
		0 = print nothing
                        	1 = print outgoing only
                        	2 = print incoming only
		3 = print both incoming and outgoing
		4-65535 = reserved
	2 = security of incoming data, DX =
                        	0 = all private
                        	1 = Faxes public
                        	2 = XFR's public
                        	3 = Faxes and XFR's public
                        	4-65535 = reserved
	3 = conversion status, DX =
		0 = no conversion
		1 = convert ASCII to PCL
		2-65535 = reserved
	4 = registration status, DX =
		0 = no registration required
		1 = registration required
		2-65535 = reserved
	5 = clear log by DX days automatically
                        	0 = do not clear by days
                        	1..65535 = clear entry after 1..65535 days
	6 = clear log by DX events automatically
                        	0 = do not clear by events
                        	1..65535 = clear after 1..65535 events in system
	7 = archival status, DX =
		0 = archive none
                        	1 = archive outgoing
                        	2 = archive incoming
		3 = archive both incoming and outgoing
		4-65535 = reserved
		8-255 = reserved
	DX = value to set, depends on option
Output:
	AX = 0 if successful or negative error code

Notes:
        This function requires server 
administrator privileges



Get/Set Board Status
Input:
	AH = multiplex #
	AL = A9h
        	BX = 0 to GET, 1 to SET
	CL = board #
	CH = board status:
		0 = deactivate board (neither send nor receive)
		1 = send only
		2 = receive only
		3 = both send and receive
		4-255 = reserved
Output:
	AX = 0 if successful or negative error code

Notes:
        This function requires server 
administrator privileges


Get/Set Retry Sequence
Input:
	AH = multiplex #
	AL = AAh
        	BX = 0 to GET, 1 to SET
	DS:DX = pointer to a 2*32 byte structure; the first 32
		bytes contain class 4 subcodes, and the following
		32 bytes contain the number of minutes to wait when
		the corresponding subcode (in the first table) is
		the cause of failure during a send event.  set unused
		bytes to 0.

Output:
	AX = 0 if successful or negative error code

Notes:
        This function requires server 
administrator privileges


Set User Profile
Input:
	AH = multiplex #
	AL = ABh
	DS:DX = pointer to user profile structure
Output:
	AX = 0 if successful or negative error code
        
This call will fill in the profile with 
updated information

Notes:
        This function requires server 
administrator privileges.  The database 
record, SET, is the one matching with Mbox 
number, i.e. Goto Mbox, Update Zero mbox, 
adds a new user.

struct UProfile {
   char Name[80];
   word Mbox;           // If zero, then consider this an ADD user
   word InBoard;
   word OutBoard;
   word Rights;
   char Password[16];
   word LastY;          // If all zeroes, then default to today when SETting
   byte LastM;
   byte LastD;
   word FirstY;         // If all zeroes, then default to today when SETting
   byte FirstM;
   byte FirstD;
};


Find User by Name
Input:
	AH = multiplex #
	AL = ACh
        	CL = next mbox: 0=forward, 1=backward
       	 DS:DX = pointer to buffer that holds partial
		user name; the buffer is filled with the user profile
Output:
	AX = 0 if successful or negative error code
        	CX = next user by mailbox [sorted in database sort order]
             		or 0 for 'this is the last mbox'

Notes:
        Unless executed by either owner or 
session with ADM_CONFIG, the Password 
field will be empty.


Find User by Mailbox
Input:
	AH = multiplex #
	AL = ADh
        	BX = mailbox #, 0=first, 0xffff=last, 1-7fff=real mbox
        	CL = next mbox: 0=forward, 1=backward
        	DS:DX = pointer to buffer; the buffer is filled with the
		user profile
Output:
	AX = 0 if successful or negative error code
        	CX = next user by mailbox [sorted in database sort order]
             or 0 for 'this is the last mbox'

Notes:
        Unless executed by either owner or 
session with ADM_CONFIG,  the Password 
field will be empty.


Kill Session
Input:
        	AH = multiplex #
        	AL = AEh
        	BX = mailbox #
Output:
        	AX = 0 if successful or negative error code
             	[Access denied, event not found]

Notes:
        This function will kill the 
session, open to the given mailbox #. If 
no session is open to that user, event not 
found will be returned. ADM_CONFIG rights 
are required for this function call.
If the user whose session just got killed 
attempts to do anything without restarting 
the WKS program, there will be a 30-60 
second delay and the WKS will return 
multiplex handler failed.
This call should only be used to terminate 
abnormally and unilaterally terminated 
sessions


Kill Mailbox
Input:
        	AH = multiplex #
        	AL = AFh
        	BX = mailbox #
Output:
        	AX = 0 if successful or negative error code

Notes:
This function first performs Kill Session 
[AEh] and then proceeds to wipe out: 
	- User profile from USERS.DB
    	- All events owned by mailbox #
      	- All directories belonging to 
mailbox #
       	- All Phonebook entries owned or 
linked to mailbox #
Use with extreme caution; there is no 
coming back to the events, PB entries or 
anything else after this command has wiped 
out the user.
Administrative rights are required to 
execute.


Who-am-I
Input:
        	AH = multiplex #
        	AL = B0h
Output:
        	AX = 0 if successfull. The only error could be multiplex
             		handler failed, which would be due to a broken link.
        	BX = mailbox #
        	CX = access rights
        	DX = session #
Notes:
Use this call to determine who-am-I, then 
use Find User By Mailbox [ADh] to find out 
rest of the user, like for example rights.  
The rights categories are specified 
separately in the header of  this 
document.


Authorize Transmission
This call verifies that the server doesn't 
object the proposed transmission.  
Checking this is not required for 
transmission, though all Alcom UI's must 
perform it. If this is not checked, an 
error may occur either at submission or 
when the event is transmitted and then it 
will happen with a more vague error code.
If FileSize is unknown, specify zero and 
embrace for collision [i.e. file size will 
not be checked against]
Input:
        	AH = multiplex #
        	AL = B1h
        	DS:DX = pointer to buffer containing relevant information about
                	attempted transmission.
Output:
        	AX = 0 if successful, otherwise one of the error or warning codes.
Errors:
        	AUT_FileSize1 = Disk storage not available, try again in 15 sec.
        	AUT_FileSize2 = Disk storage not available at all
        	AUT_TimeDate  = Adjust time/date to be now, instead
                       	 [too early transmission will violate priority and
                         	would thus be converted to "now" anyway]
        	AUT_NoSend    = user does not have any Send boards available
       	AUT_NoRecv    = This user does not have any Receive boards  
		available
        	AUT_Billing   = "Invalid billing code"
        	AUT_BillEmpty = "Billing code must be filled in"
        	AUT_BillUser  = "Invalid user code in billing field"
        	AUT_BillClient = "Invalid client code in billing field"
        	AUT_BillMatter = "Invalid matter code in billing field"
        	AUT_Quota     = "Quota exceeded"

struct Authorize {
   long FileSize;   	// Allows server to determine if enough disk space
   word Time;  	// For date/time determination
   word Date;
   byte EventType;  // CAS EventType [Send/Receive/Polled Receive]
   char phone_number[47]	// Phone number to call
   char Billing[64];    	// For authorization code checking
};


Cancel/Delete a specified event
Input:
        	AH = multiplex #
        	AL = B2h
        	BX = event # to cancel
        	CL =   0=Cancel, 1=Delete
Output:
       	AX = 0 if successfull, otherwise a negative error code
        	Possible error codes:
              	 - Event not found [CAS]
               	- Event already completed [ECAS]
               	- For current events: anything CAS could return

Notes(Cancel)
Event can be cancelled from any queue, 
regular or streamCAS, the event # is 
sufficient id.
        	Pending		Event will be 
completed with error status
       	 Current		Event will be 
aborted in the middle
        	Complete	Error code will be 
returned

Notes (Delete)
Event can be deleted from any queue, 
regular or streamCAS, the event # is a 
sufficient id.
When deleting event, it will be deleted 
once and for all, i.e. regarding original 
CAS, deleting event from LOG will also 
remove it from Receive queue and vice 
versa.
        	Pending         	Event will 
be deleted without trace
       	Current         	Error code 
will be returned
        	Complete        	Event will 
be deleted without trace


Register an ALCOM application
Input:
        	AH = multiplex #
        	AL = B3h
        	BX = 1 (hardcoded 1 just for the fun of it)
Output:
        	AX = 0 if successfull, otherwise fail with the message
             		"Single user UI licence
             		 User xxx using this program"
             		The value of AX is the MBox# of the user already using.
             		Use "find user by mailbox" to obtain the name.



Alcom's Implementation of ASN.1
The phonebook is a Borland Paradox 
database maintained by the LanFax 
Redirector server program using the 
Paradox engine.  In order to allow as much 
flexibility as possible when transferring 
data to and from the database, a special 
type of record called a Transfer Record is 
used.
A Transfer Record consists of one or more 
variable length fields, based on the 
concept of tagging instead of assigning 
each field a fixed position and length.  
Each field has the format  described 
below.
You can construct these records 
individually or simply call the library 
functions which create them automatically.

Offset	Size		Use
0		1		Field type, encoded as shown 
below
1		1		Data length; this is the 
absolute length of the data 
field.  If the data field is 
longer than 255 bytes, then a 
constructed type must be used.  
All constructed types used by 
Alcom have 2-byte length 
fields.
2		n		Data; the actual binary 
representation depends on field 
type.
The first field, the type, is encoded as 
follows:
xx......	Tag type:
00 = universal
01 = application
10 = context-specific
11 = private
..x.....	Field type:
0 = primitive type
1 = constructed type
...xxxxx	Field tag universal tags:
1 = boolean 
2 = integer 
3 = bit string 
4 = octet string 
5 = null
6 = object identifier
7 = object descriptor 
8 = external 
16 = sequence and sequence 
of 
17 = set and set of 
18 = NumericString 
19 = PrintableString 
20 = TeletexString
21 = VideotexString
22 = IA5String
23 = GeneralizedTime 
24 = UTCTime
25 = GraphicString
27 = GeneralString
Private/primitive tags used by Alcom:
	1 = entry type (S): phone, 
person, group
2 = last modification date 
(D)
3 = owner (S)
4 = index (S)
5 = identifier (S)
6 = name (A80)
7 = company (A64)
8 = country code (A10)
9 = area code (A10)
10 = phone number (A64)
11 = poll code (A32)
12 = binary transfer flag 
(S)
13 = audit information 
(A32)
14 = visibility (S): 
private, shared, public
15 = preferred time (S): 
BCD-encoded
16-31 = reserved
Private/constructed tags used by 
Alcom:
	1 = open phonebook record of 
tags
2 = default field record
3 = phonebook record
4 = search pattern record
5 = phone number; minimum 
element is phone number
6 = fax number; minimum 
element is phone number
Here's a sample record consisting of 
several data fields, both primitive and 
constructed types. It demonstrates the way 
a phone number could be encoded as either 
multiple fields, or one single field.
<11100010b><60,0>	constructed type: 
phonebook entry
	<11000001b><2><1>	entry type: 1 = 
person
	<11100110b><12>"Jones, Curt"	name
	<11001000b><12>"Alcom Corp."	company 
name
	<11100110b><21,0>	constructed type: 
fax number
		<11001000b><2>"1"	country code: "1"
		<11001001b><4>"415"	area code: 
"415"
		<11001010b><9>"694-7070"	phone 
number: "694-7070"
	<11001100b><2><0>	visibility: 0 = 
private




CAS Program Library for DOS
Constants and Data Structures
#define  TASK_QUEUE	0
#define  RECEIVE_QUEUE   1
#define  LOG_QUEUE	2

#define  TRANSMIT_QUEUE	0
#define  RECEIVE_QUEUE 	1
#define  LOG_QUEUE		2
#define  CURRENT_EVENT	0xFF

typedef unsigned char  byte;
typedef unsigned int   word;
typedef unsigned long dword;

struct CASTime
{
	byte hour;
	byte min;
	byte sec;
};

struct   edb {
	   byte  cas_maj_version;
	   byte  cas_min_version;
	   char  dir_path[68];
	   char  phone_name[13];
	   char  logo_name[13];
	   char  default_sender[32];
	   char  csid[21];
	   byte  reserved[107];
};


CAS Functions
CASGetInstalledState
Description
Determines whether the Resident Manager is 
currently installed.
Summary
 	#include <cas.h>
	int CASGetInstalledState(word &Query_type)
Input Parameter
     word &Query_type = 'OK';
Output Parameter
     None.
Return Value
returns 1 if Alcom workstation software 
version 3.0 or greater is loaded, 
otherwise it returns 0.  The regular CAS 
return value is placed in Query_type.

CASSubmitTask
Description
Submits the event specified in a Control 
File to the Resident Manager.  Before 
invoking this function, prepare a Control 
File.
Summary
     	#include <cas.h>
	int CASSubmitTask(word &Eventhandle, void far *ControlFile)
Input Parameter
void far *ControlFile   Pointer to a 
complete path and filename of a Control 
File.
Output Parameter
	word &Eventhandle;  positive event 
handle or negative CAS error code.
Return Value
Returns a positive event handle if 
successful; otherwise, returns a negative 
CAS error code.


CASAbortCurrentEvent
Description
Aborts the currently executing event.  
Aborting the event is not instantaneous. 
It can take up to 30 seconds.
Summary
     	#include <cas.h>
	int CASAbortCurrentEvent(void)
Input Parameter
     None.
Output Parameter
     None.
Return Value
Returns the event handle of the aborted 
event if successful;  otherwise, returns a 
negative CAS error code.


CASFindFirst
Description
Finds the earliest or latest event in the 
chosen queue that matches the given status 
and chronological direction.
Summary
#include <cas.h>
int CASFindFirst(word &Eventhandle, int Status, byte Direction, byte Queue)
Input Parameters
int status;    ANY_STATUS, COMPLETED, 
WAITING, DIALED, SENDING, RECEIVING, 
ABORTED, or negative CAS error code.
byte Direction;  0 (chronologically from 
the first occurring event to the last 
occurring event) or 1 (chronologically 
from the last occurring event to the first 
occurring event).
byte Queue;    TASK_QUEUE, RECEIVE_QUEUE 
or LOG_QUEUE.
Output Parameter
word &Eventhandle;  positive event handle 
or negative CAS error code.
Return Value
Returns the event handle of the event 
found if successful; otherwise, returns a 
negative CAS error code.
NOTE:  
If there are no events in the chosen queue 
that match the given status, a negative 
CAS error code is returned.  The negative 
(2's complement) of this error code is 
0204H, NO_MORE_EVENTS.


CASFindNext
Description
Finds the next event in the queue 
according to the settings of the last call 
to CASFindFirst.  Each subsequent call to 
the CASFindNext function returns the event 
handle of the next event using the same 
direction and status parameters set by the 
CASFindFirst function in the specified 
queue.
Summary
     	#include <cas.h>
	int CASFindNext(word &Eventhandle,byte Queue)
Input Parameter
     byte Queue;    TASK_QUEUE, 
RECEIVE_QUEUE, or LOG_QUEUE.
Output Parameter
	word &Eventhandle;  positive event 
handle or negative CAS error code.
Return Value
Returns the event handle of the event 
found if successful; otherwise, returns a 
negative CAS error code.
NOTE:  
If there are no events in the chosen queue 
that match the given status, a negative 
CAS error code is returned.  The negative 
(2's complement) of this error code is 
0204H, NO_MORE_EVENTS.


CASOpenFile
Description
Opens a file associated with the specified 
event.
Summary
#include <cas.h>
int CASOpenFile(int &Doshandle, word Eventnum, word Filenum, byte 
Queue)
Input Parameters
word Eventnum;  Event handle associated 
with the file to open.
word Filenum;  For events in the Receive 
Queue, either 0 for the Receive Control 
File or the number of the received file.  
This number is interpreted as follows:  
	0 - The Received Control File
	1 - First received file
	2 - Second received file
	3 - Third received file
	n - nth received file.
For events in the Task Queue and the Log, 
this function opens the Control File for 
the event.
    byte Queue;    TASK_QUEUE, 
RECEIVE_QUEUE, or LOG_QUEUE.
Output Parameter
int &Doshandle;  positive DOS file handle 
or negative CAS error code.
Return Value
Returns the DOS file handle of the opened 
file if successful;  otherwise, returns a 
negative CAS error code.
Remarks
After you obtain an event handle (either 
by scanning a queue using the CASFindFirst 
and CASFindNext functions or by creating 
an event using the CASSubmitTask 
function), you can use the CASOpenFile 
function to access the DOS file 
corresponding to the event.  CASOpenFile 
opens the Control File for events in the 
Task Queue or the Log.  This function 
opens the desired file in read-only mode 
and returns a DOSfile handle.
Whenever CASOpenFile opens a received 
file, the Resident Manager sets the 
FileStatus field in the received file's 
FTR in both the Receive Control File and 
the Log Control File.


CASDeleteFile
Description
Deletes the indicated file associated with 
the specified event.
Summary
	#include <cas.h>
	int CASDeleteFile(word Eventhandle, word Filenum, byte Queue)
Input Parameters
word Eventhandle;    Event handle 
associated with the file to delete.
word Filenum;      For events in the 
Receive Queue, either 0 for the Receive 
Control File and all that event's received 
files, or the received file's number to be 
deleted.  This number applies only to 
events in the Receive Queue and is ignored 
for events in the Task Queue and the Log.  
The number is interpreted as follows:
	0 - Delete all files associated with the specified Receive Control File 
(including the Receive Control File).
	1 - Delete the first received file associated with the event handle.
	2 - Delete second received file associated with the event handle.
	n - Delete the nth received file associated with the event handle.

byte Queue;    TASK_QUEUE, RECEIVE_QUEUE, 
or LOG_QUEUE.
Output Parameter
     None.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


CASDeleteAllFiles
Description
Deletes all the files associated with all 
the events in the specific queue.
Summary
     	#include <cas.h>
	int CASDeleteAll(byte Queue)
Input Parameter
     byte Queue;    TASK_QUEUE, 
RECEIVE_QUEUE, or LOG_QUEUE.
Output Parameter
     None.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.

CASGetEventDate
Description
Gets the date an event is scheduled to 
occur.
Summary
#include <cas.h>
int CASGetEventDate(word Eventhandle, byte Queue, struct date 
&Eventdate)
Input Parameters
word Eventhandle;    Event handle of the 
event to query.
byte Queue;    TASK_QUEUE, RECEIVE_QUEUE, 
or LOG_QUEUE.
Output Parameter
struct date &Eventdate;  If successful, 
the Eventdate structure is filled in with 
information from the specified event.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


CASSetTaskDate
Description
Changes the event's scheduled execution 
date in the Control File.  This function 
works only with events in the Task Queue.
Summary
	#include <cas.h>
	int CASSetTaskDate(word Eventhandle, struct date &Eventdate)
Input Parameters
 word Eventhandle;    Event handle of the 
event to modify.
struct date &Eventdate;  A pointer to a 
valid, filled-in date structure.
Output Parameter
	None.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.
NOTE:
Setting the date earlier than the current 
date causes the event to execute 
immediately.


CASGetEventTime
Description
Gets the time an event is scheduled to 
occur.
Summary
#include <cas.h>
int CASGetEventTime(word Eventhandle, byte 
Queue, struct time &Eventtime)
Input Parameters
     word Eventhandle;    Event handle of 
the event to query.
     byte Queue;    TASK_QUEUE, 
RECEIVE_QUEUE, or LOG_QUEUE.
Output Parameter
struct time &Eventtime;  Pointer to a 
CASTime structure.  If successful, the 
CASTime structure is filled in with 
information for the specified event.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


CASSetTaskTime
Description
Changes the event's scheduled execution 
time in the Control File.  This function 
works only with events in the Task Queue.
Summary
	#include <cas.h>
	int CASSetTaskTime(word Eventhandle, struct time &Eventtime)
Input Parameters
word Eventhandle;    Event handle of the 
event to modify.
struct time &Eventtime;  Pointer to a 
valid, filled in CASTime structure.
Output Parameter
     None.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.
NOTE:
Setting the time earlier than the current 
time will cause the event to execute 
immediately if the date is set to the 
current date.  Therefore, it is 
recommended that you change the date 
before you change the time or you may 
accidentally send an event before you 
intend to.


CASGetExternalData
Description
Returns the External Data Block (edb) in 
an edb structure.
Summary
	#include <cas.h>
	int CASGetExtDataBlock(void far *ExtDataBlock)

Input Parameter
     None.
Output Parameter
void far *ExtDataBlock;   Pointer to a 
valid edb structure.  If successful, the 
edb structure is filled with the edb 
information.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


CASAutoReceiveState
Description
Determines or sets the current state of 
the auto-receive feature.  If an event is 
in progress, the new auto-receive state 
does not take effect until the event is 
completed.
Summary
    	 #include <cas.h>
	int CASAutoReceiveState(byte Function, byte Number)
Input Parameter
byte mode;     0 to get the current 
auto-receive state.  1 to set the 
auto-receive state.  If mode is 0, Number 
returns the number of rings currently set.  
If mode is 1, the number of rings is set 
to Number.
Output Parameter
	None.
Return Value
Returns 0 if autoreceive is disabled, a 
positive number indicates the number of 
rings before the hardware answers, or 
returns a negative CAS error code.


CASGetCurrentEventStatus
Description
Gets information about the currently 
executing event.
Summary
     	#include <cas.h>
	int CASGetCurEventStatus(word &Eventnum,void far *ControlFile)
Input Parameter
     None.
Output Parameter
word &Eventnum;  event handle of the 
current event if successful;
void far *ControlFile;  Pointer to a valid 
Control Structure.  If the call is 
successful, the structure  is filled in 
with information about the current event. 
Return Value
Returns the event handle of the current 
event if successful;  otherwise, returns a 
negative CAS error code.


CASGetQueueStatus
Description
Gets status information about the 
specified queue.
Summary
#include <cas.h>
int CASGetQueueStatus(word Queue,int &NumberOfCTRF, int 
&NumberOfReceivedFiles)
Input Parameter
word Queue;    The queue to check 
(TASK_QUEUE, RECEIVE_QUEUE, or LOG_QUEUE).
Output Parameter
int &NumberOfCTRF;  current number of 
control files in the specified queue.  
int &NumberOfReceivedFiles;  current 
number of received files if Queue was 
RECEIVE_QUEUE, otherwise set to 0.
Return Value
Returns total number of changes made to 
this queue since startup if successful; 
otherwise, returns a negative CAS error 
code.


CASGetHardwareStatus
Description
Returns the hardware-specific status 
information of the communications hardware 
in a HWSTAT structure.  
Summary
    	#include <cas.h>
     	int CASGetHardwareStatus (void far *buffer);
Input Parameter
     None.
Output Parameter
void far *buffer;   Pointer to a 128-byte 
area in which hardware status information 
is returned.
Return Value
Returns 0 if successful, otherwise, 
returns a negative CAS error.


CASRunDiagnostics
Description
     Runs a set of diagnostics or reports 
on their progress.
Summary
     	#include <cas.h>
     	int CASRunDiagnostics (byte mode);
Input Parameter
byte mode;     Determines which 
diagnostics function to invoke.  Setting 
mode to a value of 1 starts the hardware 
diagnostics.  Setting mode to a value of 0 
returns the status of the diagnostics.
Output Parameter
     None.
Return Value
Depending on the action specified by mode, 
this function returns the following 
results:
1 returns 0 if successful (diagnostic 
begun); otherwise, returns a negative CAS 
error code.
0 returns 40H if the diagnostics are in 
progress.  It returns a positive value 
(other than 40H) if the diagnostics are 
completed successfully.  It returns a 
negative value if the diagnostics failed.  


CASMoveReceivedFile
Description
Moves and renames a received file to the 
directory and filename specified in 
*FileName.
Summary
#include <cas.h>
int CASMoveReceivedFile(word Eventhandle, int Filenum, void far *FileName)
Input Parameters
     word Eventhandle;   Event handle of 
the Receive event.
int filenum;     The received file to 
move.  Must be non-zero to specify a 
received file.  The number is interpreted 
as follows:
	1 - First received file
	2 - Second received file
	3 - Third received file
	n - nth received file.
char *FileName;     Pointer to a fully 
qualified NULL terminated string 
specifying the new path and filename.
Output Parameter
     None.
Return Value
     Returns 0 if successful; otherwise, 
returns a negative CAS error code.
Remarks
The path in *FileName must already exist.  
The file named by *FileName must not 
already exist or an error results.  This 
function does not create directories. The 
*FileName can specify any disk drive 
physically in the system.


CASSubmitSingleFile
Description
     Submits a Send event specified in a 
data structure to the Resident Manager.
NOTE:
To send more than one file, use the 
CASSubmitTask function.
Summary
     #include <cas.h>
     int CASSubmitSingleFile (void far *buffer);
Input Parameter
void far *buffer;  Pointer to a data 
structure containing an abbreviated 
version of the information in the Task 
Control File.   
Output Parameter
     None.
Return Value
Returns the event handle if successful; 
otherwise, returns a negative CAS error 
code.


CASUnloadResidentManager
Description
Removes the Resident Manager from memory.  
This function can be used to remove the 
Resident Manager as long as a Terminate 
and Stay Resident (TSR) has not been 
loaded after the Resident Manager, there 
is no polled send present, or the Resident 
Manager or the hardware is not busy.
Summary
     #include <cas.h>
     int CASUnloadResidentManager(void);
Input Parameter
     None.
Output Parameter
     None.
Return Value
     Returns 0 if successful; otherwise, 
returns a negative CAS error code.


Extensions to CAS Functions
SCASFindFirst
Description
Finds the earliest or latest event in the 
chosen queue that matches the given 
chronological direction.
Summary
#include <cas.h>
int SCASFindFirst(word &Eventhandle, byte &Queue, byte direc, byte 
&status, control_fmt &ControlFile)
Input Parameters
word &Eventhandle;  if specified, the 
search is started from this event, 
otherwise the first event in the given 
chronological order is found.
	byte &Queue;    TRANSMIT_QUEUE, 
RECEIVE_QUEUE, or LOG_QUEUE. 
byte direc;  0 (chronologically from the 
first occurring event to the last 
occurring event) or 1 (chronologically 
from the last occurring event to the first 
occurring event).
Output Parameter
	word &Eventhandle;  positive event 
handle or negative CAS error code.
byte &Queue;  the actual CAS queue of this 
event.  TASK_QUEUE, RECEIVE_QUEUE, 
LOG_QUEUE, or CURRENT_EVENT.
byte &status;  the extended status of this 
event.
control_fmt &ControlFile;  a 303-byte 
buffer that contains the contents of the 
Task Control File (TCF) minus the logo 
file path and cover page text.
Return Value
Returns the event handle of the event 
found if successful; otherwise, returns a 
negative CAS error code.


SCASFindNext
Description
Finds the next event in the queue 
according to the settings of the last call 
to CASFindFirst.  Each subsequent call to 
the CASFindNext function returns the event 
handle of the next event using the same 
direction parameters set by the 
CASFindFirst function in the specified 
queue.
Summary
	#include <cas.h>
int SCASFindNext(word &Eventhandle, byte &Queue, byte &status, 
control_fmt &ControlFile)
Input Parameters
	byte &Queue;    TRANSMIT_QUEUE, 
RECEIVE_QUEUE, or LOG_QUEUE. 
Output Parameter
	word &Eventhandle;  positive event 
handle or negative CAS error code.
byte &Queue;  the actual CAS queue of this 
event.  TASK_QUEUE, RECEIVE_QUEUE, 
LOG_QUEUE, or CURRENT_EVENT.
byte &status;  the extended status of this 
event.
control_fmt &ControlFile;  a 303-byte 
buffer that contains the contents of the 
TCF minus the logo file path and cover 
page text.
Return Value
Returns the event handle of the event 
found if successful; otherwise, returns a 
negative CAS error code.


SCASFind
Description
Finds the event with the given event 
handle regardless of where the event is 
currently located.  
Summary
	#include <cas.h>
int SCASFindNext(word &Eventhandle, byte &Queue, byte &status, 
control_fmt &ControlFile)
Input Parameters
word &Eventhandle;  the event handle of 
the event to be found.
Output Parameter
	word &Eventhandle;  positive event 
handle or negative CAS error code.
byte &Queue;  the actual CAS queue of this 
event.  TASK_QUEUE, RECEIVE_QUEUE, 
LOG_QUEUE, or CURRENT_EVENT.
byte &status;  the extended status of this 
event.
control_fmt &ControlFile;  a 303-byte 
buffer that contains the contents of the 
TCF minus the logo file path and cover 
page text.
Return Value
Returns the event handle of the event 
found if successful; otherwise, returns a 
negative CAS error code.


SCASForward
Description
Finds the event with the given event 
handle regardless of where the event is 
currently located.  
Summary
	#include <cas.h>
int SCASForward(word &Eventhandle, void far *ControlFile)
Input Parameters
word &Eventhandle;  the event handle of 
the event to be forwarded.
control_fmt &ControlFile;  a buffer that 
contains the path and name of the TCF.
Output Parameter
	word &Eventhandle;  positive event 
handle or negative CAS error code.
Return Value
Returns the event handle of the event 
otherwise, returns a negative CAS error 
code.


SCASPrint
Description
Prints the event with the given event 
handle.
Summary
	#include <cas.h>
	int SCASPrint(word Eventhandle, word Operation)
Input Parameters
word &Eventhandle;  the event handle of 
the event to be forwarded.
word Operation;  should be one of the 
following values:
	0 for get print status of event.
	1 print this event.
	2 don't print this event.
Output Parameter
	None
Return Value
Returns print status of the event which 
can be:
	0  this event will not be printed.
	1  event is to be printed.
	2  event is printing at this moment.
otherwise, returns a negative CAS error 
code.


SCASGetServerStatus
Description
Gets the current status of the server.
Summary
	#include <cas.h>
	int SCASGetServerStatus(void far *ControlFile)
Input Parameters
	None
Output Parameters
void far*ControlFile;  a pointer to the 
server status record, and the current 
server status is returned in it.
Return Value
Returns 0, or a negative error code.

SCASGetBoardStatus 
Description
	Gets the current status of the CAS 
boards.
Summary
	#include <cas.h>
	int SCASGetBoardStatus(void far *ControlFile, int &BoardNum)
Input Parameters
int &BoardNum;  the bank number of the 
board to be found.  One bank contains 2 
boards, valid numbers are 0-7.
Output Parameter
int &BoardNum;  number of boards available 
in the system.
void far *ControlFile;  a buffer that 
contains two structures of the BoardStatus 
type.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


SCASGetServerOption 
Description
Gets the current value from the server 
corresponding to the option specified by 
OptionNum.
Summary
	#include <cas.h>
	int SCASGetServerOption(int &OptionNum)
Input Parameters
int &OptionNum;  the server option to be 
checked.
Output Parameter
int &OptionNum;  value of the specified 
option.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


SCASSetServerOption 
Description
Sets the given OptionValue Of the server 
corresponding to the option specified by 
OptionNum.
Summary
	#include <cas.h>
int SCASSetServerOption(int OptionNum, int OptionValue)
Input Parameters
int OptionNum;  the option that is to be 
changed, valid numbers are:
	0  printer type
	1  printing status
	2  security of incoming data
	3  conversion status
	4  registration status
	5  clear log by days automatically
	6  clear log by events automatically
	7  archival status
int OptionValue;  the value of the option 
selected by OptionNum.  Check extcas.doc 
for valid values.
Output Parameter
	None
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


SCASSetBoardStatus 
Description
Gets or sets the board status of the board 
specified by BoardNum.
Summary
	#include <cas.h>
int SCASSetBoardStatus(byte BoardNum, byte &BoardStatus, int GetOpt)
Input Parameters
byte BoardNum;  the number of the board 
which is to be checked.
byte &BoardStatus;  if the intention is to 
set board status, the following values 
should be used:
	0  deactivate board
	1  allow the board to send only
	2  allow the board to receive only
	3  allow the board to send and 
receive
int GetOpt;  if it is 0 then get board 
status, if it is 1 then set board status
Output Parameter
byte &BoardStatus;  contains a previously 
described board status value.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


SCASSetRetrySequence 
Description
Gets or sets the retry time intervals, and 
the error codes which cause the server to 
retry a number.
Summary
	#include <cas.h>
int SCASSetRetrySequence(void far *InList, int GetOpt)
Input Parameters
void far *InList;  pointer to a 2*32 byte 
structure;  the first 32 bytes contain 
class 4 subcodes, and following 32 bytes 
contain the number of minutes to wait 
between each retry.
int GetOpt;  if it is 0 then get retry 
sequence, if it is 1 then set retry 
sequence
Output Parameter
void far *InList;  pointer to retry 
sequence struture mentioned above.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


SCASSetUserProfile 
Description
Set the user's rights and other user 
profile.
Summary
	#include <cas.h>
int SCASSetUserProfile(void far *UserRecord)
Input Parameters
void far *UserRecord;  pointer to a buffer 
that points to the UProfile struct
Output Parameter
None
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.

SCASFindUserByName 
Description
Gets the user's record from the given user 
name.
Summary
	#include <cas.h>
int SCASFindUserByName(void far *UserRecord)
Input Parameters
void far *UserRecord;  pointer to a buffer 
that points to the UProfile struct which 
contains the user name to be found.
Output Parameter
void far *UserRecord;  pointer to UProfile 
struct which contains the specified user's 
record.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


SCASFindUserByMbox 
Description
Gets the user's record from the given user 
mailbox ID.
Summary
	#include <cas.h>
int SCASFindUserByMbox(void far *UserRecord, int Mbox, byte direc, int      
&NextPrevMbox)
Input Parameters
int Mbox;  the mail box number to be 
searched.
byte direc;  direction for returning the  
next mail box number;  it can be one of 
the following 0 for search forward, and 1 
for search backward.
Output Parameter
void far *UserRecord;  pointer to UProfile 
struct which contains the specified user's 
record.
int &NextPrevMbox;  Id of the next user 
mailbox.  If this is the last mailbox, a 
zero is returned.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


SCASKillSession
Description
This function will terminate the session 
open to the given mail box number.
Summary
	#include <cas.h>
int SCASKillSession(int Mbox)
Input Parameters
int Mbox;  the mail box number to be 
terminated.
Output Parameter
	None
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.

SCASKillMailbox
Description
This function will terminate the specified 
mail box, and all files, directories and 
database entries associated with it.
Summary
	#include <cas.h>
int SCASKillMailbox(int Mbox)
Input Parameters
int Mbox;  the mail box number to be 
terminated.
Output Parameter
	None
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


SCASWhoAmI
Description
This function returns the mail box ID of 
the calling user, and the rights of the 
user.
Summary
	#include <cas.h>
int SCASWhoAmI(int &Mbox, word &rights, word &session)
Input Parameters
None
Output Parameter
	int &Mbox;  the mail box number of 
the current user.
	word &rights;  a bit mask of the 
current user's rights.
	word &session;  the session number of 
the current user.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.

SCASAuthorize
Description
This function verifies that the server 
doesn't object the proposed transmission. 
Summary
	#include <cas.h>
	int SCASAuthorize(void far *Autho_data)
Input Parameters
void far *Autho_data;  a pointer to 
Authorize struct with the pertinent 
information filled in.
Output Parameter
	None
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error or warning 
code.


SCASCancelEvent
Description
This function cancels or deletes a 
specified event from any queue (regular or 
extended CAS).
Summary
	#include <cas.h>
	int SCASCancelEvent(word eventnum, byte option)
Input Parameters
word eventnum;  the eventnumber of the 
event to be canceled.
byte option;  if set to 0 the event will 
be canceled, and if set to 1 the event 
will be deleted.
Output Parameter
	None
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.

SCASRegisterUI
Description
This function registers an ALCOM 
application with the server.
Summary
	#include <cas.h>
	int SCASRegisterUI(word option)
Input Parameters
word option;  reserved value, currently 
set to 1.
Output Parameter
	None
Return Value
Returns 0 if successful; otherwise, 
returns the mail box ID of the previous 
registered user.


Phonebook Functions
SCASOpenPhonebook
Description
This function opens the phone book, and 
requests information about tags specified 
in the PbRecord for future transactions.
Summary
	#include <cas.h>
	int SCASOpenPhonebook(void far *PbRecord, int &Handle, word 
&MaxNum)
Input Parameters
void far *PbRecord;  a pointer to a buffer 
containing ASN1 tags.
Output Parameter
void far *PbRecord;  a pointer to a buffer 
containing default values for the tags 
specifed.
int &Handle;  the phonebook handle 
associated with the opened phonebook.
word &MaxNum;  the number of records 
currently in the phonebook.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


SCASClosePhonebook
Description
This function closes the phone book 
associated with the given handel. 
Summary
	#include <cas.h>
	int SCASClosePhonebook(int Handle)
Input Parameters
int Handle;  the handle of the phonebook 
to be closed.
Output Parameter
	None
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.

SCASGetPhonebookStatus
Description
This function gets the current status of 
the phonebook.
Summary
	#include <cas.h>
int SCASGetPhonebookStatus(byte &NumUsers, byte &TotUsers, word 
&MaxNum, int &NumChanges)
Input Parameters
None
Output Parameter
byte &NumUsers;  number of users currently 
accessing the phonebook.
byte &TotUsers;  maximum number of 
concurrent phonebook users.
word &MaxNum;  number of entries in the 
phonebook.
int &NumChanges;  number of changes made 
in the phonebook since server startup.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


SCASFindFirstPhonebook
Description
This function finds the first phonebook 
entry.
Summary
	#include <cas.h>
int SCASFindFirstPhonebook(word Handle, void far *PbRecord)
Input Parameters
word Handle;  the phonebook handle.
Output Parameter
void far *PbRecord;  a pointer to a buffer 
containing a transfer record with 
previously specified tags.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.

SCASFindNextPhonebook
Description
This function finds the next phonebook 
entry in the given direction.
Summary
	#include <cas.h>
int SCASFindNextPhonebook(int Handle, byte Direction, void far *PbRecord)
Input Parameters
word Handle;  the phonebook handle.
byte Direction;  specify 0 for search 
forward, and 1 for search backward.
Output Parameter
void far *PbRecord;  a pointer to a buffer 
containing a transfer record with 
previously specified tags.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


SCASAddPhonebookEntry
Description
This function adds or updates a given 
phonebook entry.
Summary
	#include <cas.h>
int SCASAddPhonebookEntry(word Handle, word &index, void far 
*PbRecord)
Input Parameters
word Handle;  the phonebook handle.
void far *PbRecord;  a pointer to a buffer 
containing a transfer record of the Person 
type.
Output Parameter
word &index;  ID of the newly added 
phonebook entry.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.
Note:
If the incoming transfer record contains a 
record ID, then this will be considered an 
update instead of add.

SCASDeletePhonebookEntry
This function deletes a given phonebook 
entry.
Summary
	#include <cas.h>
	int SCASDeletePhonebookEntry(int Handle, word RecordId)
Input Parameters
word Handle;  the phonebook handle.
word RecordId;  ID of the record to be 
deleted.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


SCASAddPhonebookGroupEntry
Description
This function adds the given phonebook 
entry to a specified group.
Summary
	#include <cas.h>
int SCASAddPhonebookGroupEntry(word RecordId, word GroupId)
Input Parameters
word RecordId;  ID of the record to be 
added.
word GroupId;  ID of the group to which 
the record is to be added.
Output Parameter
None
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.

SCASDeletePhonebookGroupEntry
Description
This function deletes the given phonebook 
entry from a specified group.
Summary
	#include <cas.h>
int SCASDeletePhonebookGroupEntry(word RecordId, word GroupId)
Input Parameters
word RecordId;  ID of the record to be 
deleted.
word GroupId;  ID of the group from which 
the record is to be deleted.
Output Parameter
None
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.


SCASGetPhonebookGroupEntry
Description
This function retrievs the contents of a 
given group.
Summary
	#include <cas.h>
int SCASGetPhonebookGroupEntry(void far *GroupList, word GroupId, int 
PageNum, int &NumEntry)
Input Parameters
word GroupId;  ID of the group to be 
retrieved.
int PageNum;  specifies the block of 
records required.  0 implies the first 256 
entries, 1 means the second 256 entries 
...etc.
Output Parameter
void far *GroupList; pointer to a buffer 
large enough to hold 256 identifiers (512) 
bytes.
int &NumEntry;  number of entries in the 
buffer.
Return Value
Returns 0 if successful; otherwise, 
returns a negative CAS error code.



CAS DLL for Windows 2.x and 3.0
Target Audience and Requirements
This document is targeted at programmers 
and technical project managers who wish to 
use CAS in a Microsoft Windows programming 
environment.
The reader should be familiar with CAS as 
well as Windows terminology such as 
Dynamic Link Libraries (DLLs), and Windows 
programming concepts such as static, 
dynamic, and run-time linking.
Introduction
While CAS provides a DOS application 
interface to communication devices, it is 
difficult to access directly from Windows 
applications, particularly when running 
either Standard or Enhanced protected 
modes of Windows 3.0.
The CAS Dynamic Link Library (CAS DLL) 
provides a mechanism whereby Windows 
applications can make CAS calls in the 
same way as any normal Windows application 
program interface (API) function call, 
through a DLL interface.  Each CAS 
function is represented in the CAS DLL, 
with the addition of some new functions to 
serialise access to CAS, perform direct 
calling to CAS, control the CAS multiplex 
number and determine whether a single- or 
multi-user CAS implementation is 
installed.
CAS DLL Architecture
The CAS DLL is not a replacement for the 
CAS resident manager.  Rather, it provides 
a "clean" interface between Windows 
applications and the resident manager, 
removing the necessity for Windows 
applications to directly call the INT 2Fh 
DOS entry point for CAS, which would 
require complicated buffer and pointer 
translation depending on which version 
and/or mode of Windows the application is 
running in.
The CAS DLL also provides support for 
Windows' multi-tasking nature by providing 
multiple application re-entrancy 
protection for the underlying CAS 
interface.  This is done by serialising 
access to CAS through the CASOpen and 
CASClose functions, documented later in 
this specification.
Dynamic Link Libraries
The CAS DLL can be dynamically linked 
(implicit run-time linking, using an 
import library) or explicitly run-time 
linked (by using the Windows functions 
LoadLibrary, GetProcAddress and 
FreeLibrary in the application code) to 
Windows applications, as can any other 
Windows DLL.  The CAS DLL is provided in 
two forms, as an .EXE file compatible with 
applications running Windows 2.x, and 
Windows 2.x applications "marked" and 
running in Windows 3.0, and as a .DLL 
compatible with Windows 3.0-specific 
applications.  The functionality of the 
.EXE and the .DLL are identical; they are 
different only in that they are built with 
the Windows 2.x and 3.0 Software 
Development Kits, respectively.
Application vendors should ship only the 
version specific to the application's 
target Windows version.  The application's 
installation process should not install 
CAS DLL if an identical or newer version 
already exists on the user's system.
Import Library
Accompanying the DLL is the CASDLL.LIB 
import library which is linked with 
applications requiring to be permanently 
dynamically linked to the CAS DLL.
If an application does not need to be 
permanently dynamically linked, but 
instead needs to load the CAS DLL only 
when needed, then the import library 
should not be used.  See the section below 
entitled Explicit Run-Time Linking for 
details on how to do this.
Include File
Also provided with the CAS DLL is the 
CASDLL.H include file (C format), which 
contains all function code definitions, 
structure definitions, and function 
prototypes needed for calling the CAS DLL.  
A source module needing access to the CAS 
DLL should include the CASDLL.H file.
Calling Conventions
The CAS DLL can be called in two different 
ways, depending on the requirements of the 
developer and the application.  Descriped 
below, the two methods for linking with 
the CAS DLL are dynamic linking and 
explicit runtime linking.  The dynamic 
linking method is the recommended, and the 
easiest to use of two.
Dynamic Linking
If an application needs (or has sufficient 
memory) to be permanently dynamically 
linked to the CAS DLL, the CASDLL.LIB 
import library should be linked with the 
application.
Once dynamically linked to the 
application, the CAS DLL functions can be 
called directly, just like any of the 
standard Windows API functions.  See below 
for a description of the names and 
parameters of the CAS DLL functions.
Explicit Run-Time Linking
If for some reason the applications 
shouldn't be permanently dynamically 
linked to the CAS DLL, the CASDLL.LIB 
import library should not be linked with 
the application.  Instead, the application 
should use the Windows API functions 
LoadLibrary, GetProcAddress and 
FreeLibrary for accessing the CAS DLL.
One advantage of this method of linking is 
that the application can use the standard 
CAS function numbers (rather than verbose 
names required when permanently 
dynamically linked) to get the procedure 
addresses of the CAS DLL functrions.  This 
is done by passing the CAS function number 
(cast to an LPSTR), as defined in the 
CASDLL.H include file, to the 
GetProcAddress function, instead of the 
far pointer to a literal string containing 
the CAS DLL function name.
CAS DLL Functions
This section documents the name and 
parameters of functions in the CAS DLL.  
Only the types of the parameters are given 
herein;  for documentation on the actual 
parameter requirements and structure 
definitions refer to the DCA/Intel 
specification.
The CAS result code (the AX register 
returned from CAS) is the function's 
return value.  These result codes are 
documented in the DCA/Intel specification.


Function 0:  CASGetInstalledState
DWORD FAR PASCAL 
CASGetInstalledState(HANDLE hCAS,WORD 
QueryType,LPBYTE majVer,LPBYTE minVer)
Gets the installed state and version 
number of workstation program or switches 
workstation program ON / OFF. Returns 
state of workstation program if one of the 
three query types mentioned below is used. 
Returned state can be either 
CAS_WKSSTATE_ON (workstation activated) or 
CAS_WKSSTATE_OFF (workstation off). If 
query type is something else ("any other") 
this function works like the standard CAS-
function: returns 0x00 if workstation 
program is not installed, 0x01 if it's not 
installed and it's not OK to install or 
0xFF if it's installed. NOTE: This is a 
modified (extented) standard CAS-function.
Returns ERRCAS_INVALIDHANDLE, if invalid 
CAS-handle was used.
INPUT:
HANDLE hCAS		- CAS handle
WORD QueryType	-specifies the query type:
	CAS_WKSSTATE_OK	- report workstation state and version
	CAS_WKSSTATE_ON	- turn workstation on
	CAS_WKSSTATE_OFF	- turn workstation off
	any other         		- get state (standard CAS-function)

OUTPUT:
	LPBYTE majVer	- Far pointer to byte, which will contain 
workstation program major version number, if 
query type is one of the three mentioned above

	LPBYTE minVer	- Far pointer to byte, which will contain 
workstation program minor version number, if 
query type is one of the three mentioned above


Function 1:  CASSubmitTask
int FAR PASCAL CASSubmitTask(HANDLE hCAS, 
LPSTR lpstrTaskControl)
	Submits the task defined in the file 
named in lpstrTaskControl.
	Returns 0 if successful, or negative 
error code.
INPUT:
	HANDLE hCAS 	- CAS handle
	LPSTR 	lpstrTaskControl  - Far pointer to ASCIIZ path and name of 
Task Control File.



Function 2:  CASAbortCurrent EVENT
int FAR PASCAL  
CASAbortCurrentEvent(HANDLE hCAS)
	Aborts the currently running event.
	Returns 0 if successful, or negative 
error code.
INPUT:
	HANDLE hCAS		- CAS handle



Function 5:  CASFindFirst
int FAR PASCAL CASFindFirst(HANDLE hCAS, 
LPHEVENT lphEvent, WORD wStatus,BYTE 
byDirection, BYTE byQueue)
	Searches the queue you specify in 
byQueue for an event whose status 
matchesthe one you specify in wStatus. 
Depending on the value of byDirection the 
function searches chronologically forward 
or backward.
	Returns 0 if successful, or negative 
error code.
INPUT:
	HANDLE hCAS 	- CAS handle
	WORD wStatus		- status of the event you are seeking. 
Value is compared with the field at offset 2 of the Control Record.
		0 - event completed
		1 - waiting
		2 - dialed
		3 - sending
		4 - receiving
		5 - aborted
		-1 chooses an event without regard to status.
		BYTE byDirection  	- Search direction 
			0 forward chronologically
			1 backward
		BYTE byQueue		- queue to search
			0 - task queue
			1 - receive queue
			2 - log queue

OUTPUT:
	LPHEVENT lphEvent - event handle for the first found event.



Function 6:  CASFindNet
int FAR PASCAL  CASFindNext(HANDLE hCAS, 
LPHEVENT lphEvent, BYTE byQueue)
	Finds the next event that matches 
search criteria specified in previous 
CASFindFirst -call.
	Returns 0 if successful, or negative 
error code.
INPUT:
	HANDLE hCAS 	- CAS handle
	BYTE byQueue		- queue to search
		0 - task queue
		1 - receive queue
		2 - log queue

OUTPUT:
	LPHEVENT lphEvent - event handle for the next found event.



Function 7:  CASOpenFile
int FAR PASCAL CASOpenFile(HANDLE hCAS, 
LPHANDLE lphFile, HEVENT hEvent,WORD 
wFileNumber, BYTE byQueue)
	Opens the Control File for specific 
event. For incoming events (in receive 
queue) you can also 	specify this 
function to open one of the received 
files.
	Returns 0 if successful, or negative 
error code.
INPUT:
	HANDLE hCAS 	- CAS handle
	HEVENT  hEvent	- event handle
	WORD wFileNumber	- ignored for Log and Task Queue 
events. For Receive Queue events specifies which file to open among those 
associated with a receive event.
		0 - The Receive Control Record
		1 - First received file
		2 - second received file
		n - nth received file
	BYTE byQueue		- specifies the queue
		0 - task
		1 - receive
		2 - log

OUTPUT:
  LPHANDLE lphFile- Far pointer to DOS file handle of  requested file


Function 8:  CASDeleteFile
int FAR PASCAL CASDeleteFile(HANDLE hCAS, 
HEVENT hEvent, WORD wFileNumber,BYTE 
byQueue)
	Deletes file in specific queue.
	Returns 0 if successful, or negative 
error code.
INPUT:
	HANDLE hCAS 	- CAS handle
	HEVENT  hEvent	- event handle
	WORD wFileNumber	- ignored for Log and Task Queue 
events. For Receive Queue events specifies which file to delete among those 
associated with a receive event.
		0 - The Receive Control Record
		1 - First received file
		2 - second received file
		n - nth received file
	BYTE byQueue		- specifies the queue
		0 - task
		1 - receive
		2 - log


Function 9:  CASDeleteAll
int FAR PASCAL CASDeleteAll(HANDLE hCAS, 
BYTE byQueue)
	Deletes all files in the specified 
queue.
	Returns 0 if successful, or negative 
error code.
INPUT:
	HANDLE hCAS	- CAS handle
	BYTE byQueue  - queue:
		0 - delete all control files in task queue
		1 - delete all control files in receive queue, received files
		2 - delete all control files in log queue



Function 10:  CASGetEventDate
int FAR PASCAL CASGetEventDate(HANDLE 
hCAS, LPDATE lpDate, HEVENT hEvent,BYTE 
byQueue)
	Gets date of event or server date, if 
event number 0x7FFFF.
NOTE: This is a modified (extented) 
standard CAS-function.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE  hCAS 	- CAS handle
	HEVENT hEvent  	- Event handle of the event whose date you want 
to obtain.  Specify 0x7FFF if you want to obtain server date.
	BYTE byQueue		- Queue number of queue where the 
event can be found.  Not needed for server date.

OUTPUT:
	LPDATE  lpDate	- Far pointer to DATE-structure, which CASDLL 
will fill with date-information.


Function 11:  CASSETTaskDate
int FAR PASCAL CASSetTaskDate(HANDLE hCAS, 
HEVENT hEvent, DATE Date)
	Sets the date of specific event or 
server date, if event number is 0x7FFFF.
	Returns 0 if successful or negative 
error code.
NOTE: This is a modified (extented) 
standard CAS-function.
INPUT:
	HANDLE hCAS 	- CAS handle
	HEVENT hEvent	-Event handle of the event whose date you want 
to change.  Specify 0x7FFF if you want change server date.
	DATE  Date   		 - DATE-structure, which has the new 
event/server date value.


Function 12:  CASGetEventTime
int FAR PASCAL CASGetEventTime(HANDLE 
hCAS, LPTIME lpTime, HEVENT hEvent,BYTE 
byQUEUE)
	Gets time of event or server time, if 
event number is 0x7FFFF.
NOTE: This is a modified (extented) 
standard CAS-function.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS 	- CAS handle
	HEVENT hEvent  	- Event handle of the event whose time you want 
to obtain. Specify 0x7FFF if you want to obtain server time.
	BYTE 	byQueue	- Queue number of queue where the 
event can be found.  Not needed for server time.

OUTPUT:
 	 LPTIME lpTime		- Far pointer to TIME-structure, which 
CASDLL will fill with time information.


Function 13:  CASSetTaskTime
int FAR PASCAL CASSetTaskTime(HANDLE hCAS, 
HEVENT hEvent, TIME Time)
	Sets time of event or server time, if 
event number is 0x7FFFF.
NOTE: This is a modified (extented) 
standard CAS-function.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS 	- CAS handle
	HEVENT hEvent	-Event handle of the event whose time you want to 
change.  Specify 0x7FFF if you want change server time.
	TIME Time   		 - TIME-structure, which has the new 
event/server time value.


Function 14:  CASGetExtDataBlock
int FAR PASCAL CASGetExtDataBlock(HANDLE 
hCAS, LPEDB lpedbExternalData)
	Gets External Data Block, which 
contains additional information you might 
need.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS 	- CAS handle

OUTPUT:
	LPEDB lpedbExternalData - Far pointer to EDB-structure, which is 
filled with External Data Block information


Function 15:  CASAutoReceiveState
int FAR PASCAL CASAutoReceiveState(HANDLE 
hCAS, BYTE byFunction, BYTE byNumber)
	Gets or sets the autoreceive state of 
hardware = number of rings before the 
hardware answers.
	Returns current autoreceive state if 
successful, 0 if autoreceive disabled or 
negative error code.
INPUT:
	HANDLE hCAS 	- CAS handle
	BYTE byFunction 	- function code
		0 - get current autoreceive state
		1 - set current autoreceive state to value in byNumber
	BYTE byNumber	- # of rings before answer (0=disable)


Function 16:  CASGetCurEventStatus
int FAR PASCAL CASGetCurEventStatus(HANDLE 
hCAS, LPHEVENT lphEvent,LPSTATUSBLOCK 
lpsbStatus)
	Gets the status of currently 
executing event.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS 	- CAS handle

OUTPUT:
	LPHEVENT lphEvent 	- Far pointer to event number of the 
current event
	LPSTATUSBLOCK lpsbStatus 	- Far pointer to STATUSBLOCK 
- structure, which CAS fills with a truncated version of Control Record for 
current event.


Function 17:  CASGetQueueStatus
int FAR PASCAL CASGetQueueStatus(HANDLE 
hCAS, LPQINFO lpQueueInfo, BYTE byQueue)
	Gets the current status of a queue 
you specify.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS 	- CAS handle
	BYTE byQueue   	- Queue, whose status is to be obtained
		0 - task queue
		1 - receive queue
		2 - task queue

OUTPUT:
	LPQINFO lpQueueInfo - Far pointer to QINFO structure, which this 
function fills with current status information.


Function 18:  CASGetHWStatus
int FAR PASCAL CASGetHWStatus(HANDLE hCAS, 
LPHWSTATUS lpHWStatus)
	Gets hardware-dependent status 
information about the communication 
hardware.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS 		- CAS handle
OUTPUT:
	LPHWSTATUS lpHWStatus 	- Far pointer to HWSTATUS 
structure, which this function fills with current status information.


Function 19:  CASRunDiags
int FAR PASCAL CASRunDiags(HANDLE hCAS, 
BYTE byMode)
	Runs set of diagnostics or reports on 
their progress. 
	If request was to start running 
diagnostics, returns 0 if successfully 
begun or negative error  code. If request 
was to report the progress of diagnostics, 
returns 0x40 if diagnostics in  progress, 
positive number if successfully completed 
or negative error code. The values are 
hardware-dependent.
INPUT:
	HANDLE hCAS 	 - CAS handle
	BYTE byMode    	- operation mode:
		0 - report progress of diagnostics
		1 - start running diagnostics


Function 20:  CASMoveFile
int FAR PASCAL CASMoveFile(HANDLE hCAS, 
HEVENT hEvent, WORD wNumber,LPSTR 
lpstrFileSpec)
	Moves a received file to a different 
directory and gives it a new name.
Note: The path to new directory must 
exists. This function cannot create 
directories.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS 		- CAS handle
	HEVENT hEvent		- event handle, received event
	WORD wNumber 		- receive file number
		1 - first received file
		2 - second received file
		n - nth received file
	LPSTR lpstrFileSpec - Far pointer to new path and name of the file 
(ASCIIZ format).  This file must not exist already.


Function 21:  CASSubmit1File
int FAR PASCAL CASSubmit1File(HANDLE hCAS, 
LPSFTC lpSingleFileTaskControl)
	Submits a single file, either as a 
fax or as a file transfer.
	Returns a positive event handle if 
successful, or negative error code.
INPUT:
	HANDLE hCAS 		- CAS handle
	LPSFTC  lpSingleFileTaskControl - Far pointer to SFTC-structure 
which contains  information about the file to be submitted.


Function 129:  CASSetMultiPlex
int FAR PASCAL CASSetMultiPlex(HANDLE 
hCAS, BYTE byValue)
	Set the CAS multiplex value to 
byValue. Updates default multiplex value 
in WIN.INI (section: 	[CASDLL] line: 
Multiplex). Default multiplex value is 
0xCB.
	NOTE: In following versions of 
CASDLL.DLL, which support multiple 
multiplex handlers, 	this function 
changes only multiplex value corresponding 
to CAS-handle.
	Returns 0, if successful or 
ERRCAS_INVALIDHANDLE if invalid CAS-handle 
was used.
INPUT:
	HANDLE hCAS		- CAS handle
	BYTE byValue 		- new multiplex value



Function 130:  CASSingleUser
int FAR PASCAL CASSingleUser(HANDLE hCAS)
	Current CASDLL is a single user 
version, so this function returns SINGLE 
always if successful 	or 
ERRCAS_INVALIDHANDLE if invalid CAS-handle 
was used.
INPUT:
	HANDLE hCAS 	- CAS handle


Function 131:  CASGetMultiPlex
int FAR PASCAL CASGetMultiPlex(HANDLE 
hCAS)
	Returns the current CAs multiplex 
value, if successful or 
ERRCAS_INVALIDHANDLE if	invalid CAS-
handle was used.
NOTE: In following versions of CASDLL.DLL, 
which support multiple multiplex handlers, 
this function returns multiplex value, 
which CAS-handle hCAS is using.
INPUT:
	HANDLE hCAS 	- CAS handle


Function 132:  CASCall
int FAR PASCAL CASCall(HANDLE hCAS, BYTE 
CASFunc, LPWORD lpCASbx, LPWORD lpCAScx, 
LPWORD lpCASdx, LPVOID lpBuf,WORD 
wBufSize, WORD wBufFlags)
	Makes a CAS call using user defined 
register values. It will typically be used 
for calling OEM-	specific 
"undocumented" CAS functions.  If calling 
a function taking a CAS-style buffer 
pointer 	(always DS:DX in the DCA/Intel 
specification), use the lpBuf, BufSize and 
wBufFlags 	parameters to describe the 
buffer and what needs to be done with it .
	If not passing a buffer to CAS, 
simply set lpBuf to NULL and BufSize to 
zero (wBufFlags is 	ignored).
	Returns value AX-register if 
successful or ERRCAS_INVALIDHANDLE if 
invalid
	CAS-handle was used.
INPUT:
	HANDLE hCAS		- CAS handle
	BYTE CASFunc		- CAS function number
	LPWORD lpCASbx	- Far pointer to value of BX-register
	LPWORD lpCAScx	- Far pointer to value of CX-register
	LPWORD lpCASdx	- Far pointer to value of DX-register (can 
not be used with lpBuf)
	LPVOID lpBuf		- Far pointer to data buffer, CASDLL 
passes this pointer to CAS in DS:DX register pair.
	WORD wBufSize	  - Size of data buffer, if == 0 then data buffer is 
not used.
	WORD wBufFlags  	- Direction flags for databuffer:
	  CWB_IN        copy buffer in (down) to CAS (BEFORE CAS call)
	  CWB_OUT    copy buffer out (up) from CAS (AFTER CAS call)
	  CWB_INANDOUT  copy buffer before AND after calling CAS

OUTPUT:
	LPWORD lpCASbx	- Far pointer to value of BX-register
	LPWORD lpCAScx	- Far pointer to value of CX-register
	LPWORD lpCASdx	- Far pointer to value of DX-register (valid 
only if lpBuf is not used)


Function 144:  PCASOpenPB
int FAR PASCAL PCASOpenPB(HANDLE hCAS, 
LPWORD lpPbNumEnt, LPWORD lpPbCASh,LPVOID  
pbTR, WORD bufSZ)
	Opens the phonebook and provides the 
calling application a handle to phonebook. 
The phonebook handle must be used when 
calling PCASFindFirst and PCASDFindNext 
functions.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS	- CAS handle
	LPVOID pbTR	- Far pointer to Transfer record of the 
OpenPhonebook type
	WORD bufSZ	- Size of the Transfer Record pointed by pbTR

OUTPUT:
	LPWORD lpPbNumEnt 	- Far pointer to number of entries in 
phonebook
	LPWORD lpPbCASh	- Far pointer to a new phonebook handle


Function 145:  PCASClosePB
int FAR PASCAL PCASClosePB(HANDLE hCAS, 
WORD pbCASh)
	Closes the phonebook instance 
specified by phonebook handle.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS	- CAS handle
	WORD pbCASh	- handle to phonebook to be closed


Function 146:  PCASGetStat
int FAR PASCAL PCASGetStat(HANDLE hCAS, 
LPBYTE lpPbCU, LPBYTE lpPbMCU,LPWORD 
lpPbNumOE, LPWORD lpPbNumOC)
	Gets the phonebook status.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS		- CAS handle

OUTPUT:
	LPBYTE lpPbCU	- Far pointer to number of users currently 
accessing the phonebook
	LPBYTE lpPbMCU	- Far pointer to max. number of 
concurrent phonebook users
	LPWORD lpPbNumOE	- Far pointer to number of entries in the 
phonebook
	LPWORD lpPbNumOC	- Far pointer to number of changes 
made into the phonebook  since server startup


Function 147:  PCASFindFirst
int FAR PASCAL PCASFindFirst(HANDLE hCAS, 
WORD pbCASh, LPVOID pbTR, WORD bufSZ)
	Finds the first phonebook entry that 
matches the search pattern specified in 
Transfer Record. NOTE: This function often 
returns error because the access rights 
may not allow you to see the first/last 
entry of the phonebook. To find the 
first/last visible entry call PCASFindNext 
right
	after failed PCASFindFirst.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS	- CAS handle
	WORD pbCASh	- Phonebook handle
	LPVOID pbTR- Far pointer to a buffer containing a transfer record of 
the SearchPattern type; the buffer must be large enough to contain any found 
entry.
	WORD bufSZ- size of Transfer Record pointed by pbTR.

OUTPUT:
	LPVOID pbTR- Far pointer to a buffer containing a transfer record of 
found phonebook entry.


Function 148:  PCASFindNext
int FAR PASCAL PCASFindNext(HANDLE hCAS, 
BYTE pbDirection, WORD pbCASh,LPVOID  
pbTR, WORD bufSZ)
	Finds the next or previous phonebook 
entry that matches the search pattern 
given in PCASFindFirst -call.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS	- CAS handle
	WORD pbCASh	- Phonebook handle
	BYTE pbDirection - search direction
		 0 - search forward
		 1 - search backward
	WORD bufSZ	- size of Transfer Record pointed by pbTR.

OUTPUT:
	LPVOID pbTR- Far pointer to a buffer containing a transfer record of 
found  phonebook entry.


Function 149:  PCASAddEntry
int FAR PASCAL PCASAddEntry(HANDLE hCAS, 
LPWORD lpIndex, WORD pbCASh,LPVOID pbTR, 
WORD bufSZ)
	Adds a new entry to phonebook or 
updates an existing one. If Transfer 
record contains ID, and 	the ID already 
exists, this will be considered a UPDATE 
instead of ADD. If Transfer record 
	contains ID, and the ID does not 
exist, this will be considered a error.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS	- CAS handle
	WORD pbCASh	- Phonebook handle
	LPVOID pbTR	- Far pointer to a Transfer Record of the Person 
type
	WORD bufSZ  - size of Transfer Record pointed by pbTR

OUTPUT:
	LPWORD lpIndex - Far pointer to identifier of the newly added entry 
in the phonebook


Function 150:  PCASDeletePBEntry
int FAR PASCAL PCASDeletePBEntry(HANDLE 
hCAS, WORD pbCASh, WORD pbIDdelete)
	Deletes an entry from phonebook.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS		- CAS handle
	WORD pbCASh		- Phonebook handle
	WORD pbIDdelete 	- Identifier of the entry to delete


Function 151:  PCASAddEntry2Group
int FAR PASCAL PCASAddEntry2Group(HANDLE  
hCAS, WORD pbIDgroup, WORD pbCASh,WORD 
pbIDadd)
	Adds entry to phonebook group.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS		- CAS handle
	WORD pbCASh		- Phonebook handle
	WORD pbIDgroup	- identifier of the group
	WORD pbIDadd		- identifier of the entry to add


Function 152:  PCASDeleteEntryFromGroup
int FAR PASCAL 
PCASDeleteEntryFromGroup(HANDLE hCAS, WORD 
pbIDgroup,WORD pbCASh, WORD pbIDdelete)
	Deletes an entry from phonebook 
group.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS		- CAS handle
	WORD pbCASh		- Phonebook handle
	WORD pbIDgroup	- identifier of the group
	WORD pbIDadd		- identifier of the entry to delete


Function 153:  PCASGetEntriesOfGroup
int FAR PASCAL 
PCASGetEntriesOfGroup(HANDLE hCAS, WORD 
wGroup,  LPWORD lpEntries,WORD wPage,  
LPVOID lpEntryBuf, WORD bufSZ)
	Gets identifiers of entries found in 
a specific phonebook group.
	Returns 1 if more entries to come, 0 
if last page of group or negative error 
code.
INPUT:
	HANDLE hCAS		- CAS handle
	WORD pbCASh		- Phonebook handle
	WORD wGroup		- identifier of the group
	WORD wPage		- page number
		0 - first 256 entries
		1 - entries from 256 to 511
		3 - entries from 512 to 767
		etc.
	WORD bufSZ		- size of buffer to contain 256 identifiers 
= 512 bytes

OUTPUT:
	LPWORD lpEntries 	- number of entries in buffer
	LPVOID lpEntryBuf 	- Far pointer to buffer large enough to 
hold at least 256 identifiers (size 512 bytes)


Function 160:  SCASFindFirst
int FAR PASCAL  SCASFindFirst(HANDLE hCAS, 
LPHEVENT lphEvent, LPBYTE lpbyQueue,BYTE 
byDir, LPBYTE lpbyExtStatus, LPSTR 
lpstrTaskControl)
	Searches the server stream queue you 
specify in lpbyQueue for first, last or 
specific event.
	To find first event in queue, set 
event handle pointed by lphEvent to 0 and 
set byDir = 0.
	To find last event in queue, set 
event handle pointed by lphEvent to 0 and 
set byDir = 1.
	To find a specific event, set event 
handle pointed by lphEvent to even number 
you want to 	obtain. Note: if a 
specified event could not be found then no 
error is returned but is rather 	assumed 
to be meant to be 0, which is used for 
searching the first event in queue.
	Returns 0 if successful or a negative 
error code.
INPUT:
	HANDLE hCAS		- CAS handle
	LPHEVENT lphEvent 	- Far pointer to event handle, which 
should be 0 for regular  find first or last. Other than 0 attempts to position 
based on event number.
	LPBYTE lpbyQueue	-Far pointer to server stream queue to 
search,  NOTE: these are not the same as CAS queues
		0 - transmit queue
		1 - receive queue
		2 - log queue
		3-255 - reserved
	BYTE byDir		- Search direction
		0 - forward chronologically, finds first event in queue
		1 - backward chronologically, finds last event in queue

OUTPUT:
	LPHEVENT lphEvent 	- Far pointer to event number of found 
event.
	LPBYTE lpbyQueue	- Far pointer to actual CAS queue 
number this event is found.
		0 - transmit queue
		1 - receive queue
		2 - log queue
		0xFF - current event
	LPBYTE lpbyExtStatus	- Far pointer to extended status
		0 - event has no pending operations
		1 - event will be printed
		2 - event is printing
	LPSTR lpstrTaskControl	- Far pointer to a 303 byte buffer; this 
buffer will be filled  with the events Control Record minus the logo file path


Function 161:  SCASFindNext
int FAR PASCAL  SCASFindNext(HANDLE hCAS, 
LPHEVENT lphEvent, LPBYTE lpbyQueue, 
LPBYTE lpbyExtStatus,  LPSTR 
lpstrTaskControl)
	Finds the next event in specific 
server stream queue.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS			- CAS handle
	LPBYTE lpbyQueue	- Far pointer to server stream queue to 
search.  NOTE: these are not the same as CAS queues
		0 - transmit queue
		1 - receive queue
		2 - log queue
		3-255 - reserved

OUTPUT:
	LPHEVENT lphEvent	- Far pointer to event handle of found 
event.
	LPBYTE lpbyQueue	- Far pointer to actual CAS queue 
number this event is found.
		0 - transmit queue
		1 - receive queue
		2 - log queue
		0xFF - current event
	LPBYTE lpbyExtStatus	- Far pointer to extended status
		0 - event has no pending operations
		1 - event will be printed
		2 - event is printing
	LPSTR lpstrTaskControl	- Far pointer to a 303 byte buffer; this 
buffer will be filled with the events Control Record minus the logo file path


Function 162:  SCASFind
int FAR PASCAL  SCASFind(HANDLE hCAS, 
LPHEVENT lphEvent, LPBYTE lpbyQueue,LPBYTE  
lpbyExtStatus, LPSTR lpstrTaskControl)
	Finds a specific event in server 
stream queues.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS		- CAS handle
	LPHEVENT lphEvent	- Far pointer to event number to find

OUTPUT:
	LPHEVENT lphEvent	- Far pointer to event handle of found 
event.
	LPBYTE lpbyQueue	- Far pointer to actual CAS queue 
number this event is found.
		0 - transmit queue
		1 - receive queue
		2 - log queue
		0xFF - current event
	LPBYTE lpbyExtStatus	- Far pointer to extended status
		0 - event has no pending operations
		1 - event will be printed
		2 - event is printing
	LPSTR lpstrTaskControl	- Far pointer to a 303 byte buffer; this 
buffer will be filled with the events Control Record minus the logo file path


Function 163:  SCASForward
int FAR PASCAL SCASForward (HANDLE hCAS, 
LPHEVENT lphEvent, LPSTR lpstrTaskControl)
	Forwards a specific event to a new 
recipient.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS		- CAS handle
	LPHEVENT lphEvent	- Far pointer to event number to forward.
	LPSTR lpstrTaskControl 	- Far pointer to name of new Task 
Control File, which includes information about new recipient.

OUTPUT:
	LPHEVENT lphEvent	- Far pointer to event handle of new 
forwarded event.


Function 164:  CASPrintEvent
int FAR PASCAL CASPrintEvent(HANDLE hCAS, 
HEVENT hEvent, BYTE byOper)
	Print or get printing status of 
specific event.
	Returns print status or negative 
error code. Status may have following 
values:
		0 - This event will not be 
printed
		1 - Event is to be printed
		2 - Event is printing at the 
moment
INPUT:
	HANDLE hCAS	 	- CAS handle
	HEVENT hEvent	- handle of event to print
	BYTE byOper   		- print operation
		0 - Get print status of event
		1 - Print this event
		2 - Don't print this event


Function 165:  CASGetServerStatus
int FAR PASCAL CASGetServerStatus(HANDLE 
hCAS, LPSRVSTAT lpSrvStat)
	Gets server status information.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS		- CAS handle

OUTPUT:
	LPSRVSTAT lpSrvStat	- Far pointer to SRVSTAT-structure, 
which contains information about server status


Function 166:  CASGetBoardStatus
int FAR PASCAL CASGetBoardStatus(HANDLE 
hCAS, BYTE byBank, LPBYTE lpbyBoards,LPSTR 
lpStatus)
	Gets board status information. Boards 
are arrenged in banks of two boards.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS		- CAS handle
	BYTE byBank		- bank number 0 - 7, one bank contains 
two boards

OUTPUT:
	LPBYTE lpbyBoards	- Far pointer to number of boards 
available.
	LPSTR lpStatus		- Far pointer to buffer containing two 
BRDSTAT -structures.


Function 167:  CASGetSrvOption
int FAR PASCAL CASGetSrvOption(HANDLE 
hCAS, BYTE byOption, LPWORD lpValue)
	Gets server option information of 
specific option.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS	 - CAS handle
	BYTE byOption	- Option number
		0 - printer type
		1 - printing status
		2 - security of incoming data
		3 - conversion status
		4 - registration status
		5 - clear log by days automatically
		6 - clear log by events automatically
		7 - archival status
		8-255 - reserved

OUTPUT:
	LPWORD lpValue 	-Far pointer to option value printer type:
		1 = LaserJet II, 300 dpi
		2 = LasetJet II, 100 dpi
		3 = LaserJet IIP, 300 dpi
		4 = LaserJet IIP, 100 dpi
		5 = LaserJet III, 300 dpi
		6 = LaserJet III, 100 dpi
		7-65535 = reserved

	printing status:
		0 = print nothing
		1 = print outgoing only
		2 = print incoming only
		3 = print both incoming and outgoing
		4-65535 = reserved

	security of incoming data:
		0 = all private
		1 = Faxes public
		2 = XFR's public
		3 = Faxes and XFR's public
		4-65535 = reserved

	conversion status:
		0 = no conversion
		1 = convert ASCII to PCL
		2-65535 = reserved

	registration status:
		0 = no registration required
		1 = registration required
		2-65535 = reserved

	clear log by specified number of days automatically
		0 = do not clear by days
		1..65535 = clear entry after 1..65535 days

	clear log by specified number of events automatically
		0 = do not clear by events
		1..65535 = clear after 1..65535 events in system

	archival status:
		0 = archive none
		1 = archive outgoing
		2 = archive incoming
		3 = archive both incoming and outgoing
		4-65535 = reserved
		8-255 = reserved


Function 168:  CASSetSrvOption
int FAR PASCAL CASSetSrvOption(HANDLE 
hCAS, BYTE byOption, WORD wValue)
	Sets specific server option to value 
wValue.
	NOTE:	This function requires 
server administrator privileges.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS	- CAS handle
	BYTE byOption	- Option number
		0 - printer type
		1 - printing status
		2 - security of incoming data
		3 - conversion status
		4 - registration status
		5 - clear log by days automatically
		6 - clear log by events automatically
		7 - archival status
		8-255 - reserved
	WORD wValue	-New option value

	printer type:
		1 = LaserJet II, 300 dpi
		2 = LasetJet II, 100 dpi
		3 = LaserJet IIP, 300 dpi
		4 = LaserJet IIP, 100 dpi
		5 = LaserJet III, 300 dpi
		6 = LaserJet III, 100 dpi
		7-65535 = reserved

	printing status:
		0 = print nothing
		1 = print outgoing only
		2 = print incoming only
		3 = print both incoming and outgoing
		4-65535 = reserved

	security of incoming data:
		0 = all private
		1 = Faxes public
		2 = XFR's public
		3 = Faxes and XFR's public
		4-65535 = reserved

	conversion status:
		0 = no conversion
		1 = convert ASCII to PCL
		2-65535 = reserved

	registration status:
		0 = no registration required
		1 = registration required
		2-65535 = reserved

	clear log by specified number of days automatically
		0 = do not clear by days
		1..65535 = clear entry after 1..65535 days

	clear log by specified number of events automatically
		0 = do not clear by events
		1..65535 = clear after 1..65535 events in system

	archival status:
		0 = archive none
		1 = archive outgoing
		2 = archive incoming
		3 = archive both incoming and outgoing
		4-65535 = reserved


Function 169:  CASGetSetBrdStatus
int FAR PASCAL CASGetSetBrdStatus(HANDLE 
hCAS, BOOL bSet, BYTE byBoardNo,LPBYTE 
lpbyStatus)
	Gets or sets board status.
	NOTE: This function requires server 
administrator privileges.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS		- CAS handle
	BOOL bSet   		- Get/Set -flag
		0 - get status
		1 - set status
	BYTE byBoardNo	- Board number
	LPBYTE lpbyStatus	- Far pointer to board status
		0 - deactivate board (neither send nor receive)
		1 - send only
		2 - receive only
		3 - both send and receive
		4-255 - reserved

OUTPUT:
	LPBYTE lpbyStatus	- Far pointer to board status
		0 - deactivate board (neither send nor receive)
		1 - send only
		2 - receive only
		3 - both send and receive
		4-255 - reserved


Function 170:  CASGetSetRetrySeq
int FAR PASCAL CASGetSetRetrySeq(HANDLE 
hCAS, BOOL bSet, LPVOID lpSeqBuf)
	Gets or sets retry sequence.
	NOTE: This function requires server 
administrator privileges.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS		- CAS handle
	BOOL bSet   		- Get/Set -flag
		0 - get retry sequence
		1 - set retry sequence
	LPVOID lpSeqBuf	- If SETRetrySeq
		Far pointer to a 2*32 byte structure; the first 32 bytes 
contain class 4 subcodes, and the following 32 bytes contain the number of 
minutes to wait when the corresponding  subcode (in the first table) is the 
cause of failure during a send event.  set unused bytes to 0.

OUTPUT:
	LPVOID lpSeqBuf	- If GETRetrySeq
	Far pointer to a 2*32 byte structure; the first 32 bytes contain class 4 
subcodes, and the following 32 bytes contain the number of minutes to wait 
when the corresponding subcode (in the first table) is the cause of failure 
during a send event.


Function 171:  CASSetUserProfile
int FAR PASCAL CASSetUserProfile(HANDLE 
hCAS, LPUPROFILE lpProfBuf)
	Adds new user or changes user profile 
information of existing one.
NOTE:	This function requires server 
administrator privileges.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS		- CAS handle
	LPUPROFILE lpProfBuf	- Far pointer to UPROFILE structure. Set 
MBox-field of this structure to 0 to add a new user.


Function 172:  CASFindUserName
int FAR PASCAL CASFindUserName(HANDLE 
hCAS, BYTE byDir, LPWORD 
lpNextMbox,LPUPROFILE lpProfBuf)
	Finds user profile information based 
on partial user name.
NOTE: Unless executed by either owner or 
session with ADM_CONFIG, the Password 
field will be empty.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS	- CAS handle
	BYTE byDir	- direction
		0 - returns next mailbox ID in lpNextMbox
		1 - returns previous mailbox ID in lpNextMbox
	LPUPROFILE lpProfBuf 	- Far pointer to UPROFILE-structure, 
whose Name-field contains partial user name

OUTPUT:
	LPWORD lpNextMbox -	Far pointer to next/previous mailbox ID
	LPUPROFILE lpProfBuf 	- Far pointer to UPROFILE-structure, 
which is filled with the user profile


Function 173:  CASFindUserMbox
int FAR PASCAL CASFindUserMbox(HANDLE 
hCAS, BYTE byDir, LPWORD lpMbox,LPUPROFILE 
lpProfBuf)
	Finds user profile information based 
on mail box ID.
NOTE: Unless executed by either owner or 
session with ADM_CONFIG the Password field 
will be empty.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS		- CAS handle
	BYTE byDir		- direction
		0 - returns next mailbox ID in lpMbox
		1 - returns previous mailbox ID in lpMbox
	LPWORD lpMbox 	- Far pointer to mailbox ID of user to be 
found

OUTPUT:
	LPWORD lpMbox	 - Far pointer to next/previous mailbox ID
	LPUPROFILE lpProfBuf 	- Far pointer to UPROFILE-structure, 
which is  filled with the user profile


Function 174:  CASKillSession
int FAR PASCAL CASKillSession(HANDLE hCAS, 
WORD wMbox)
	Kills session open to specific 
mailbox number.
	NOTE: ADM_CONFIG rights are required 
for this function call. If the user whose 
session just got killed attempts to do 
anything without restarting the WKS 
program, there will be a 30-60 second 
delay and the WKS will return multiplex 
handler failed. This call should only be 
used to terminate abnormally and 
unilaterally terminated sessions.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS - CAS handle
	WORD wMbox 	- mailbox number of owner of session to be 
closed.


Function 175:  CASKillMbox
int FAR PASCAL CASKillMbox(HANDLE hCAS, 
WORD wMbox)
	Removes a specific mailbox.
NOTE: This function first performs Kill 
Session [AEh] and then proceeds to wipe 
out:
	- User profile from USERS.DB
	- All events owned by mailbox #
	- All directories belonging to 
mailbox #
	- All Phonebook entries owned or 
linked to mailbox #
Use with extreme caution; there is no 
coming back to the events, PB entries or 
anything else after this command has wiped 
out the user. ADM_CONFIG rights is 
required to execute.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS - CAS handle
	WORD wMbox 	- number of the mailbox to removed.


Function 176:  CASWhoAmI
int FAR PASCAL CASWhoAmI(HANDLE hCAS, 
LPWORD lpMbox, LPWORD lpAccess,LPWORD 
lpSession)
	Finds the mailbox number of calling 
workstation.
NOTE: Use this call to determine who-am-I, 
then use CASFindUserName to find out rest 
of the 	user, like for example rights.
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS - CAS handle

OUTPUT:
	LPWORD lpMbox 	- Far pointer to mailbox number
	LPWORD lpAccess 	- Far pointer to access rights
	LPWORD lpSession 	- Far pointer to session number


Function 177:  CASAutTransmission
int FAR PASCAL CASAutTransmission(HANDLE 
hCAS, LPAUTTRANS lpAutBuf)
	Verifies that the server doesn't 
object the proposed transmission. Checking 
this is not required 	for transmission. 
If this is not checked, an error may occur 
either at submission or when the 	event 
is transmitted and then it will happen 
with a more vague error code. If FileSize 
is
	unknown, specify zero and embrace for 
collision (i.e. file size will not be 
checked against).
	Returns 0 if successful or negative 
error code.
INPUT:
	HANDLE hCAS 	- CAS handle
	LPAUTTRANS lpAutBuf - Far pointer to AUTTRANS structure, which 
contains information about proposed transmission.


Function 178:  CASCancelEvent
int FAR PASCAL CASCancelEvent(HANDLE hCAS, 
HEVENT hEvent, BOOL bDel)
	Cancel or delete specified event. 
Event can be cancelled from any queue, 
regular or streamCAS, 	the event number 
is sufficient id.
	Pending         Event will be 
completed with error status
	Current         Event will be aborted 
in the middle
	Complete        Error code will be 
returned
	Event can be deleted from any queue, 
regular or streamCAS, the event number is 
a sufficient id.
	When deleting event, it will be 
deleted once and for all, i.e. regarding 
original CAS, deleting 	event from LOG 
will also remove it from Receive queue and 
vice versa.
	Pending         Event will be deleted 
without trace
	Current         Error code will be 
returned
	Complete        Event will be deleted 
without trace
Returns 0 if successful or negative error 
code.
INPUT:
	HANDLE hCAS 	 - CAS handle
	HEVENT hEvent  	- event number to cancel or delete
	BOOL bDel		 - cancel/delete flag
		 0 - cancel event
		1 - delete event


Function 179:  CASRegAlcomApp
int FAR PASCAL CASRegAlcomApp(HANDLE hCAS)
	Register an ALCOM application.
	Returns 0 if successfull, otherwise 
the return value is the mailbox number of 
the user already using this program. Use 
CASFindUserMbox to obtain the name.
INPUT:
	HANDLE hCAS 	- CAS handle


Function 200:  CASOpen
HANDLE FAR PASCAL CASOpen(HANDLE 
hInstance, WORD wMode)
	Opens CAS for the calling instance.
	If successful, returns CAS-handle, 
which must be used by that instance for 
all subsequent CAS operations.  If no free 
CAS-handles are available, returns 
ERRCAS_INVALIDHANDLE if wMode is 
CO_NOPROMPT, displays a messagebox and 
return ERRCAS_INVALIDHANDLE if wMode is 
CO_PROMPTOK or asks user to close other 
instance using CASDLL and try again if 
wMode is CO_RETRYCANCEL.
INPUT:
	HANDLE 	hInstance - instance handle of the calling 
application instance.
	WORD 		wMode     -	specifies what action to take if 
no free CAS-handles are available. It must have one of the following values:
		value		 - action
		CO_NOPROMPT - simply returns error code 
ERRCAS_INVALIDHANDLE
		CO_PROMPTOK - shows a message box telling no CAS-
handles were  available and returns error code ERRCAS_INVALIDHANDLE to 
calling instance when user presses OK-button.
		CO_RETRYCANCEL - shows a message box asking user 
to close other application using CASDLL. Tries to open CAS again if user 
presses RETRY-button or return error code ERRCAS_INVALIDHANDLE if 
user presses CANCEL-button.


Function 201:  CASClose
int FAR PASCAL CASClose(HANDLE hCAS)
	Releases CAS-handle specified by 
hCAS.  Indicates that the calling 
application has finished 	using CAS. 
Do not use CAS-handle for other CAS 
operations after calling this function. 
Some other instance may have already 
allocated it for its own use.
	Returns 0 if CAS-handle was freed, 
error code ERRCAS_INVALIDHANDLE if CAS-
handle was already free.
INPUT:
	HANDLE 	hCAS	- CAS-handle to be closed.


Function 202:  CASResetFindNext
int FAR PASCAL CASResetFindNext(HANDLE 
hCAS)
	Tells CASDLL that application has 
finished using this CAS-handle for 
CASFindNext calls. Next time this 
application wants to use CASFindNext it 
has to call CASFindFirst first.
NOTE: This is not a CAS-function. It 
exists only to support multiple 
application instances all using 
CASFindFirst / CASFindNext calls.
NOTE: StreamCAS-functions can be used 
simultaneously by multiple instances 
without needing to call CASResetFindNext.
	Returns 0 if successful, or negative 
error code.
INPUT:
	HANDLE hCAS 	- CAS handle


Data Structures
SRVSTAT record

struct {
	char RevNum[6];		// server version "3.0"
	DWORD UpTime;	// # of seconds since startup
	BYTE IdleBoards;	// # of idle boards
	BYTE TotalBoards;	// total # of boards
	WORD IPSendEvents;	// # of send events in process
	WORD RecEvents;	// # of received events
	WORD SendEvents;	// # of send events
	WORD CurrUsers;	// # of users logged in
	WORD TotalSrvUsers; 	// # of users available [server]
	WORD TotalNetUsers; 	// # of users available [network]
	WORD Mailboxes;	// # of mailboxes in use
	WORD TotalMailboxes;	// total # of mailboxes
	DWORD DiskSpace;	// # of bytes available at server disk
	DWORD DiskSize;	// # of bytes at server
	DWORD ArchSpace;	// # of bytes available at archive site
	DWORD ArchSize;	// # of bytes at archive site
	DWORD RamConv;	// # of bytes conventional memory
	DWORD RamExt;	// # of bytes external memory available
	DWORD RamTotalExt;	// # of bytes external memory
	BYTE RamType;		// type of external memory
	WORD Options;		// server options
	BYTE ParadoxNOS;	// NOS for Paradox
	WORD TotalEvents;   	// Total # of events available
	WORD Events;        	// # of events in use
}

LPSRVSTAT - Far pointer to SRVSTAT

#####

BRDSTAT record

struct {
	char CapBoard;	// board capabilities
	char StatBoard;	// board status
	char SenderName[80];
	char DestName[80];
	char PhoneNum[50];
	WORD ConnectionTime;
}

LPBRDSTAT - Far pointer to BRDSTAT

#####

UPROFILE record

struct {
	 char Name[80];
	 WORD Mbox;           // If zero, then consider this an ADD user
	 WORD InBoard;
	 WORD OutBoard;
	 WORD Rights;
	 char Password[16];
	 WORD LastY;          // If all zeroes, default to today when SETting
	 BYTE LastM;
	 BYTE LastD;
	 WORD FirstY;         // If all zeroes, default to today when SETting
	 BYTE FirstM;
	 BYTE FirstD;
}

LPUPROFILE - Far pointer to UPROFILE

#####

AUTTRANS record

struct {
	 long FileSize;       // Allows server to check if enough disk space
	 WORD Time;           // For date/time determination
	 WORD Date;
	 BYTE EventType;      // EventType [Send/Receive/Polled Receive]
	 char phone_number[47];// Phone number to call
	 char Billing[64];    // For authorization code checking
} 

LPAUTTRANS - Far pointer AUTTRANS

#####

DATE record

struct {
	WORD Day	:5;
	WORD Month 	:4;
	WORD Year	:7;
} 

LPDATE - Far pointer to DATE

#####

TIME record

struct {
	WORD Second	:5;
	WORD Minute	:6;
	WORD Hour	:5;
} 

LPTIME - Far pointer to TIME

#####

QINFO record

struct {
	WORD nChanges;	// Total number of changes made to
				// this queue since server was started
	WORD nControlFiles;	// Current number of Control Files in 
				//this queue
	WORD nReceived;	// Current number of received files.
				// Non-zero only for receive queue
}   

LPQINFO - Far pointer to QINFO

#####

FILE_TRANSFER_RECORD record
FILETREC record

struct {
	unsigned char	filetype;
	unsigned char 	font;
	unsigned char 	status;
	long 		bytes;
	long 		totbytes;
	int 		pages;
	int  		totpages;
	char                  	filename[80];
	unsigned char	pagelen_8ths;
	unsigned char 	pagelen_inches;
	char      		pad[31];
}

LPFILETREC - Far pointer to FILE_TRANSFER_RECORD

#####

CONTROL_RECORD record
CONTROLREC record
struct {
	unsigned char 	eventtype;
	unsigned char 	xfertype;
	int		status;
	int 		dostime;
	int 		dosdate;
   	int 		totalfiles;
	int 		ftroffset;
	char 		phonenum[47];
	char 		isvtag[64];
	char 		reserved1;         // pulled the reserved byte out
	unsigned char 	duration_secs;     // of isvtag[] AndyV 8/20/91
	unsigned char	duration_mins;
	unsigned char 	duration_hours;
	long 		totalpages;
	long 		npages;
	int 		nfiles;
	unsigned char	coverflag;
	int 		 nerrors;
	char 		reserved[78];
	char 		csid[21];
	char 		destname[32];
	char 		sender[32];
	char 		logopath[80];
}

LPCONTROLREC - Far pointer to CONTROL_RECORD CONTROLREC  

#####

STATUSBLOCK record

struct {
	CONTROL_RECORD        cr;
	FILE_TRANSFER_RECORD  ftr;
} 

LPSTATUSBLOCK - Far pointer to STATUSBLOCK

#####

EDB record 

struct {
	unsigned char	majorver;
	unsigned char 	minorver;
	char  		defdirectory[68];
	char   		defphonebook[13];
	char   		deflogo[13];
	char  		sender[32];
	char  		csid[21];
	char  		pad[107];
} 

LPEDB - Far pointer to EDB

#####

SFTC record

struct {
	unsigned char	xfertype;
	unsigned char  	font;
	int   		dostime;
	int 		dosdate;
	char 		destname[32];
	char  		filepath[80];
	char 		phonenum[47];
	char 		isvtag[65];
	unsigned char	coverflag;
	char	 	reserved[23];
	char		text[COVERLINES*COVERWIDTH];
} 

LPSFTC - Far pointer to SFTC

####

HWSTATUS record

struct {
	char  	flag[14];
	int  	errorcnt;
	long 	filelen;
	char	pad[10];
	char 	csid[21];
} 

LPHWSTATUS - Far pointer to HWSTATUS



Appendix A:  Configuration 
Overview
The SETUP program adjusts a configuration 
file at the LanFax Redirector server 
called LANFAX.CFG.  While this file is 
normally created at installation time and 
adjusted by SETUP, some of the parameters 
can be accessed only through the file 
itself.  This Appendix contains a complete 
description of the configuration file and 
the meaning of its contents.
The LANFAX.CFG configuration file is an 
ASCII file, with one configuration option 
on each line.  The maximum line length is 
512 characters. Lines are terminated with 
carriage return and line feed (CRLF), 
although plain LF is accepted. Empty lines 
will be read in, and are considered to be 
comment lines. Empty lines will not be 
preserved.  Every time the server 
terminates normally, it will write the 
file out with its current configuration 
parameters.
Each option is represented by a three-
character code.  Numbers are always 
decimal.  Lists are delimited with commas 
or semicolons and there must be a 
delimiter separating two items.  (Some 
commands require commas, some require 
semicolons as documented below.)  No 
spaces are allowed unless they are 
specifically required.  Each line is of 
the format
	xxx=value
where xxx is the option to be specified 
and value is the value to assign to it.  
For example, the line
	prt=0
means that the printer is disabled.
It is intended that this file not be 
touched/viewed by users, only by Alcom 
Product Support and 
configuration/installation programs.


Options
Enable printer - prt
prt=0	Printing not enabled
prt=6	Printing enabled, HP LaserJet 
III, resolution = 300 dpi
Allowed values are:
	0	printer not enabled
	1	LaserJet II, 300 dpi
	2	LaserJet II, 100 dpi
	3	LaserJet IIP, 300 dpi
	4	LaserJet IIP, 100 dpi
	5	LaserJet III, 300 dpi
	6	LaserJet III, 100 dpi
Set Printer Port - prp
prp=1	Printer port, LPT1, this is 
ignored (see prf)
Set printer device/file - prf
prf=PRN	Default printer device/port is 
PRN, LanFax Redirector will 
open/close device/file at 
beginning/end of print job to 
make sure network print spoolers 
will flush job. File will be 
opened in shareable binary 
write-only mode.
The handle is opened with OPEN, READWRITE, 
BINARY, DENYNONE.  An IOCTL SET_RAW_MODE 
is also attempted on the device handle.  
If writing to a file, the file must 
already exist.  It will be overwritten, 
but not truncated.
Set database locations - dbu, dbp, dba
dbu=C:\LANFAX\DB\
Where USERS database is to be 
located.  Terminating \ is 
required.
dbp=C:\LANFAX\DB\
Where PHONE database is to be 
located.  Terminating \ is 
required.
dba=C:\LANFAX\DB\
Where AUDIT database is to be 
located.  Terminating \ is 
required.
Board Scan Frequency - bsc
bsc=1	Scan one board per second. This 
is satisfactory for more than 
four boards.  For one board, 5 
seconds is recommended.  No harm 
will happen if boards are 
scanned too frequently, but some 
CPU time will be wasted.
Paradox Network Operating System - nos
nos=1	Location of databases and 
underlying network operating 
system (if databases are on a 
network drive).  If the 
databases are local to the 
server, you must choose 1 (Not 
on Network).
Allowed values are:
	1 = Not on net
	2 = Novell
	3 = 3Com
	4 = 3Com 3+Open
	5 = Other net, DOS 3.1 compatible
	7 = AT&T Starlan
	8 = Banyan
	9 = IBM PC NET
	32 = Local Share; add this to some 
other value, e.g. OtherNet 
		if multitasking locally and 
network SHARE compatible
Paradox Sort Order - prs
pxs=a	This parameter sets the sorting 
order for the Paradox database 
files (users, phonebook, audit 
trail).
Allowed values are:
  	a	ASCII
	i	International
	n	Norwegian/Danish
	f	Finnish/Swedish
Default  Send/Receive Board Rights - dsb, 
drb
dsb=-1	By default every new user gets 
full rights to all boards.  The 
value for rights is constructed 
by adding together the bit mask 
values listed below.  The bit 
mask for all rights is the sum 
of all of the values, or -1.   
Suppose however, that one board 
(#1) is not for general use.  
Define dsb=-2.   This means that 
the rights for board #1 (with a 
value of 1) are not available to 
all users by default because the 
value 1 has been subtracted from 
the rights mask.  Suppose that 
board #2 is only meant for the 
CEO to send out.  To do this, 
define the default send rights 
dsb=-4, and then for the CEO 
define dsb=-2 in the USERS 
database (or via the user 
interface).
Bit mask values are:

  
Boa
rd
All 
Right
s on 
Board


   
1
1


   
2
2


   
3
4


   
4 
8


   
5
16


   
6
32


   
7
64


   
8
128


   
9
256


  
10
512


  
11
1024


  
12
2048


  
13
4096


  
14
8192


  
15 
16384


  
16
-
32768

Server Name - svn
svn=ALCOM_LFR
Define the name of the server. 
Maximum length 16 characters, 
use only uppercase ASCII letters 
A through Z, numerals 0 through 
9 and underscore '_'.
Set Incoming Xfers/Faxes Public/Private - 
xpf, fpf
xpf=1 	Set incoming binary file 
transfers to be public (1) or 
private (0) by default.  
fpf=1	Set incoming faxes to be public 
(1) or private (0) by default.
Require Users to be Registered - reg
reg=1 	Registering is not required, 
i.e. new users can just log in 
and they will be added to system 
rosters.  If this is set to 0, 
then all users have to be pre-
registered by adding them to 
USERS.DB with either a database 
tool (Visual Basic, 
ObjectVision, Paradox, etc), 
from the workstation user 
interface or by executing 
CAS_SET_UPROFILE with MBox set 
to 0 (add new).
Set Debug Level - deb
deb=0 	For debugging purposes only. Not 
to be used by customers unless 
so directed by Alcom Product 
Support.
Allowed values are:
  	0 	No debugging information on 
screen
  	1 	Almost all functions notified
  	2 	All functions and even 
subfunctions notified
  Levels 1 and 2 slow down server 
considerably.
Number of Buffers - buf
buf=200 	Number of communication buffers 
to allocate.    Communnication 
buffers are always allocated 
from conventional memory and 
they are 512 bytes each.  The 
number of communication buffers 
sets the speed at which 
simultaneous uploads can happen. 
This number should not go below 
the maximum number of 
simultaneous, active logged on 
users. Also it shouldn't be set 
to below 30.  The range of 
allowed values is 15 to 250.
Event Cache buffer - cac
cac=254 	Event cache buffer. This makes 
the server run much faster.  
Buffers are 512 bytes if taken 
from conventional and 1K if 
taken from EMS or XMS.  LanFax 
Redirector will automatically 
take cache buffers from EMS/XMS 
if they are available and it is 
allowed to use EMS/XMS.
Database Cache - dbc
dbc=32	Paradox database cache size. 
Increasing this will increase 
performance of database 
operations. Note however that 
this cache is always taken from 
conventional memory.  Do not go 
below 32K or Paradox may not 
start up.  The range of allowed 
values is 16 to 256K.
Paradox NET file Location - pxn
pxn=C:\LANFAX\
Where the Paradox lock file is 
located. On local installations 
(all databases on local disk) 
this should point to the server 
directory, on networked 
installation it should point to 
the directory where all the 
database files are located OR to 
the networked Paradox program 
location.
HP PCL Font Path - hpp
hpp=-FC:\TD\TYPE\
Where the scaleable font files 
(*.TYP) files are located.  This 
should usually be C:\TD\TYPE\, 
but it can be set to other 
directories also.  Typeface font 
files must be synchronized with 
AgfaSync (embedded in server 
installation program) to make 
them work.  The -F must always 
be present.  Use the AgfaUtil 
program to synchronize fonts 
separately.
HP PCL Soft Font Path - sft
sft=C:\LANFAX\SFT\
Location of soft font files 
(*.SFT).
Paradox Maximum Table Size - pxm
pxm=64	Paradox max table size, for 
Paradox Engine to determine 
internal buffer size (1, 2 or 
4K).  Corresponds to a maximum 
table size of 64, 128 and 256 
megabytes respectively.
Paradox Maximum Record Locks - pxr
pxr=1 	Number of Paradox locks. If 
databases are not shared with 
other applications (Quattro Pro, 
Paradox or ObjectVision) then 
this  should be set to 1 to 
speed things up and decrease 
memory consumption.  If used 
with heavily locking 
applications then a higher 
number must be used.
Archival volume path
arc=  	not implemented
Automatic Print of Incoming/Outgoing Faxes 
- prs
prs=0 	Specifies whether faxes should 
be printed automatically.
Allowed values:
	0	Printing disabled
	1	Print all outgoing
	2	Print all incoming 
	3	Print both incoming and outgoing
Notify Administrators - adn, adm
adn=SUPER 	Notify administrative 
user(s) of all 1/Incoming faxes, 
2/Errors, 4/Successes, 8/Public 
incoming messages.  
adm=user1,user2,user3
Specify which users are to be 
notified.
This requires a native transport layer 
(Novell or Banyan) and will notify all 
users noted in the list regardless of 
whether they are logged on (on LanFax 
Redirector server, not fileserver) or not.
Notify Users - usn
usn=3 	Notify regular users about their 
events IF THEY ARE LOGGED ON 
LanFax Redirector (and 
fileserver).   
1=Incoming,2=Errors,4=Success,8=
Public
Default Administrator Rights - dea
dea=32765	Default rights for new 
administrative users (users 
logging on first time, provided 
that non-registered users are 
allowed to log on).   
Recognizing that a new user is 
an administrator requires a 
native transport layer (Novell, 
3Com, Banyan).  0x7ffd grants 
all but ADM_NOENTRY/ADM_FIND
Default User Rights - deu
deu=0 	Default rights for regular users 
logging on first time.  0x0000 
grants no special rights
Bit mask values are: (add values together 
to construct the rights bit mask)
 1	1	Router rights
 2	2	Admin find rights
 4	3	Admin delete rights
 8	4	Admin delete all rights
16	5	Admin configuration rights
32	6	 Admin cancel rights
64	7	Admin phonebook access rights
128	8	Rush jobs
256	9	Download with DL parameter
-32768	16	Lockout, blacklist this 
user

Retry Times - ret
ret=5,10,15,15,15
How many times to retry and at 
what intervals.  Given string 
will retry five times, first 
time after 5 minutes, second at 
10, etc.  Supply all intervals 
with commas delimiting.  Maximum 
32 retries can be specified.
Retry Reasons - rtr
rtr=2,3,5,6,11,13,99
Retry reasons as Class 4 
subcodes of given fax card.  The 
retry reasons are fax card 
dependant and some cards do not 
support all retry reasons (as 
SatisFAXtion).  Maximum 32 
reasons can be specified.  
Although class 4 subcodes are 
usually listed in hexadecimal, 
they must be in decimal here.
Prefix Code for Phone Numbers - pre
pre=  	Prefix phone number to dial to 
get "out in the open".  If 
server is installed within a 
PBX, supply the prefix to get 
out, usually 9 or 0.
Postfix Code for Phone Numbers - pos
pos=  	If there is a need for postfix 
to dial out, supply it here.  
Override Character - ove
ove=! 	If a phone number starts with 
override character, then normal 
prefix (if any) is not added. If 
a phone number ends with 
override character then normal 
postfix (if any) is not added.
Default Country Code - cco
cco=1 	Default country code to always 
display as a default when 
constructing/editing a new entry 
to phone book. If not supplied, 
then international phone number 
handling is off.
Default Area Code - aco
aco=415 	Default area code, see cco.
Default visibility for Phonebook - vis
vis=1 	Default visibility for new 
phonebook entries. 
  0/Shared - Anyone can add, 
anyone can view/edit/delete 
  1/Private - Anyone can add, 
only user and phonebook 
administrator can 
view/edit/delete  
  2/Public - Only phonebook 
administrator can add, anyone 
can view, only phonebook 
administrator can edit/delete
Escape Country Code - ecc
ecc=011 	Escape country code; if cco does 
not match with number in phone 
number, then what should be 
prefixed to phone number?
  - USA 011
  - Finland   990
Escape Area Code - eac
eac=1 	Escape area code; if aco does 
not match with area code in 
phone number (assuming country 
codes did match), then what 
should be prefixed to phone 
number?
 - USA 1
 - Finland   9
Administrator Name for Notification - adm
adm=user1  	List of users to send 
notifications (classified with 
adn) and fatal messages 
regardless of their logged on 
status.  A list of any number of 
entries can be specified, e.g.
 
adm=TOTALA,RMEFFORD,RNEWSOM,KKUL
ANDA
Convert ASCII to PCX Too - cas
cas=0 	Should ASCII also be rasterized 
through PCL engine, or are fax 
card fonts sufficient? Plain 
ASCII will be rasterized using 
fixed pitch 12 
COURIER.1=rasterize, 0=do not.
Archive Type - art
art=0 	Not implemented yet.
Clear Log By Date Automatically - cld
cld=0 	Clear all entries from log, 
older than x days.  Specifying 0 
will not clear any entries by 
age.
Clear Log by Entries Automatically - cle
cle=0 	Clear all entries in excess of x 
beginning with oldest.  
Specifying 0 will not clear any 
entries by volume.
Enable International Phone Number Handling 
- iph
iph=0 	This option tells UI's (through 
ServerStatus, bit SSO_INTPHONE, 
value 0x0200) whether to handle 
phone numbers in cco/aco/pco or 
just pco.  It also affects the 
server, whether it tries to 
splice/handle the phonenumbers 
or not.  For Least-Cost-Routing, 
this option is required on.  If 
INTPHONE is in, UI's should barf 
at non-standard phone numbers.  
(0=no,1=yes)
Withhold Last Session - wls
wls=1 	Whether or not the Login 
procedure should reserve the 
last session for notifying 
anyone who tries to log in that 
all sessions have been 
exhausted. The reason for this 
option is that some networks 
crash if an attempt is made to 
have one more session than 
possible. On some networks the 
number of available sessions is 
unreliable.   (0=no,1=yes)
Cache Databases - cau, cap, caa
cau=1 	WriteCache databases. This means 
that modifications are not 
written immediately to the 
database but rather after  they 
no longer can be kept in memory 
or if the server terminates.  
1=yes, 0=no.  This has no effect 
when the databases are stored on 
a network drive.
Reasons to use:
 - quite a bit faster database handling.
Reasons not to use:
 - if database is to be shared between 
multiple real-time applications like for 
example multiple servers
 - if there is a possibility of a power 
failure or frequent hardware malfunction
Even if writecaching is off it is still 
beneficial to maximize the "dbc" cache 
size [default 32k] because read-cache will 
always be on.
Multiplex Numbers of Fax Boards - brd
brd=203 	List all the fax board 
multiplexes here.  i.e. if four 
boards in four consecutive 
multiplexes, specify
	brd=203,204,205,206
  Remember always to also 
specify rights to all boards, 
otherwise 0=nothing is assumed.
Board Rights bits - brb
brb=3 	Board rights, same order as in 
brd.  NOTE: Specify same number 
of items as in brd.  
0=noth,1=send,2=recv,3=both
Paradox Database Passwords - prp
pxp=  	An arbitrary length list of 
Paradox passwords can follow.  
If any of the four databases are 
encrypted (password protected), 
then all the passwords must be 
listed here separated with "," 
(comma).

The default is empty, i.e. no 
passwords are defined.  To start 
using passwords, an external 
application must be used to 
encrypt the database initially, 
putting a password here does not 
enforce protection, it merely 
allows the server to access the 
protected database.
To protect a database, use either Paradox 
3.5 or PXEngine 2.0 call PXTblEncrypt(). 
If the four databases are all protected, 
list all the passwords, if the passwords 
are the same, then list it only once.
Paradox 3.5 Auxiliary passwords are not 
needed/used by LanFax Redirector.  Supply 
the Master password.  (With auxiliary 
passwords it is possible to restrict 
access by field, i.e. grant access to all 
except User-DB password for example.)
Transport Layer Commands - cmd
cmd=20	Number of active pending 
commands to issue to network 
layer. On NetBIOS, Server 
transport layer will issue 20 
pending RECEIVE_ANY (with name 
number specified) plus 1 pending 
LISTEN (to establish new 
connections) plus an arbitrary 
number of SEND when need arises.  
So constantly the number of 
pending items is 20+1 and the 
rest (usually 32-21=11) is 
reserved for sending packets 
out.
On networks like TOPS, the maximum number 
of pending commands for everyone is 16, so 
this should be reduced to e.g. 8.  On 
Novell/IPX this number has no effect.  
This number must never be less than buf.
PCL Conversion Command Line Parameters - 
cdc
cdc=-Ipcl -Odcx	PCL conversion command 
line.   
	-Ipcl	Input files are of 
type PCL
  	-Odcx 	Output files are of 
type DCX
	-Tpath	Temporary 
drive/directory path (600K free)
	-Bnn	Intellifont Buffer memory 
size (Kb)
	-Cnn	Intellifont Cache  memory 
size (Kb)
	-Sc 	Soft font file support 
(Autoload)
	-Mc 	FAX Mode resolution (S, 
F)
	-Hc 	Special Fax Header type
	-Zfname	Default page using 
LaserFax PCX image
	-A	Append to the output file
	-c  	Use CONTROL.PCL file to 
set default
	-s 	Write out short pages
	-mnn	Max RAM available to 
program (0=ALL)
	-zfname	PCX based FAX image 
for Manual Paper 
Defaults for flags if not given on command 
line:
	-T  	TEMP environment variable or 
current drive
	-B  	automatic optimal allocation
	-C  	automatic optimal allocation
	-Mf 	fine mode 200x200 dpi
	-m0 	(all currently available memory)
Change Converted Name - nch
nch=1 	Some fax cards don't recognize 
that a file is DCX regardless of 
its extension.  If the FTR 
(portion of TCF) explains that a 
file is DCX the card should take 
it as directly. Some CCP drivers 
do not accept this and the 
converted files (PCL->DCX or 
ASCII->DCX) need to be renamed 
to DCX for faxing.  
Unfortunately, if someone tries 
to reschedule an event with the 
.DCX file extension, it won't be 
found on the local hard 
disk...Try nch=0 (don't rename 
files to .DCX) and if it works 
with converted ASCII files leave 
it at 0.  Otherwise use 1, and 
you will not be able to 
reschedule events which consist 
of ASCII and/or PCL files.
Use EMS/XMS Memory - mem
mem=3 	XMS=1, EMS=2, Both=3, allow 
using particular kind of memory 
for caching events. By disabling 
one of these, the memory will be 
preserved for use with VROOMM or 
PCL Conversion.
Specify Memory for VROOMM - vrm
vrm=3 	EXT=1, EMS=2, Both=3, allow 
using memory for VROOMM.  By 
disabling this feature, some 
memory manager problems could be 
solved and memory could be 
conserved for use with Cache or 
PCL Conversion.
Set Default Logo File - lgo
lgo=LANFAX.PCX  
The default logo file to be used 
at workstations.  If the name is 
that of a logo file on the 
server, the workstations will 
then be able to download it.
Black and White Mode - bnw
bnw=0 	Use bwn=1 for monochrome 
monitors.  This is required to 
make the cursor and the early 
warning system visible on the 
screen.  Use bnw=0 for color 
displays.
Congestion Level - con
con=1 	How quickly/easily should the 
server go into congested-mode 
(suspending conversion)?  The 
count here specifies how many 
waiting packets may occur before 
block-out should be invoked.
	0 	first packet causes 
suspension
	1	second packet causes 
suspension
	65535	system never 
suspends conversion.
Block-Time - bti
bti=9 	This parameter specifies how 
long to suspend conversion while 
waiting and servicing further 
calls.  When the system 
encounters enough (con=1) 
waiting packets, it will go into 
suspend mode, temporarily 
stopping conversion while 
waiting for more packets to come 
in.  If any packet comes in 
within (bti=9) 9 ticks (9 * 54 
msec = 494 msec = half second) 
then the system will wait for 
another 9 ticks before resuming 
conversion.  This takes care of 
burst mode packet requests like 
download/view/update-
queues/read-in-a-page-of-
phonebook.
NOTE: * Do not use values higher than 5 
seconds (91 TICKS) * The value 0 will 
merely degrade performance.  To disable 
block-out specify con=65535.  Values 
higher than 10 seconds (182 TICKS) are 
likely to suspend conversion forever if 
there are any user interfaces in idle mode 
since they poll the server frequently 
enough to make it stay in suspended mode 
forever.
Print Priority - ppi
ppi=1	Print PrIority.  Specifies how 
many scanlines to print per 
rasterized token when 
conversions and printing are 
happening simultaneously.  1= 
ScanLine:Token, 2=2SL's:Token  
Possible range is 0 to 255, but 
only 1 to 10 are recommended.  
The only case when the CPU get's 
congested is when both printing 
and converting coincide. This 
setting makes it possible to 
configure at that point which 
takes precedence.  Handling one 
token of PCL job takes more time 
than printing one scan line, so 
the speed of printing drops 
dramatically while doing 
conversions.  The value zero 
will serve to suspend printing 
while conversion is in progress.  
Printing will resume when 
conversions are done.  Beware 
however, that this requires the 
network print timeout to be set 
to indefinite.
Library Path - lib
lib=C:\LANFAX
Where to find files which have 
an * (asterisk) in front of 
them.
Number of File Handles - fil
fil=150	This option specifies how many 
file handles the file system may 
consume to speed up access to 
events.   It can be as high as 
200 provided that the network 
drivers do not consume file 
handles.  It can be as low as 
10, though this will only 
degrade performance without any 
benefits.
The recommended  value for LanFax 
Redirector is 200, but since for example 
Banyan 4.10 opens about 55 handles and 
there are other file handle consumers also 
in play now, a more conservative default 
was adopted.
  A worst case scenario might be:
 Initial 255  (Maximum for DOS)
 Banyan  -55
 PCL Conversion  -12 
 8 Boards -8  (SatisFAXtion opens 
only one filehandle)
 Server   -3  (Server uses 3 handles 
internally)
 VROOMM   -1
 DOS-3  (DOS has 3 default 
filehandles)
Phonebook Number Separators - pbs
pbs=+ -().[]   	The default set of 
phone number separators, the 
first one must be the initiator 
of the sequence.  The following 
are all the ignored separators 
(which however are taken to mean 
separators between country code, 
area code and the actual 
number). This variable has no 
meaning if international phone 
number handling is off.
Download Path for Administrator Users - dlp
dlp=C:\;C:\LANFAX\DB
This is like lib but dlp is only 
available to Administrative 
users.  When a download is 
requested, for administrators, 
the dlp path is tried first and 
then the lib path.  For regular 
users only lib is tried.
Page Headers - phe
phe=0	This option specifies what the 
server should do to page 
headers. On top of each page 
(with Intel SatisFAXtion) there 
is a line of text describing 
sender/recipient/pages/etc.  By 
default the server doesn't do 
anything to this information, 
it's at the mercy of the user 
interfaces. Since so few user 
interfaces know about the 
possibility to affect this, it's 
implemented at the server.
	 0 means that server will 
leave it as the UI's set it, 
usually this means "always on"
	 1 makes server force it 
always on (might be for example 
a company policy)
	 2 makes server force it 
always off. This makes the pages 
nicer looking if the submitting 
application then takes care of 
the relevant issues 
(names/pages/time/etc)
Accepted Tokenizer Errors - tok
tok= 	A list of allowed tokenization 
errors for PCL Conversion.  
Regular HP LaserJet II and III 
printers allow unrecognized 
tokens to go by without 
complaining. This has lead some 
developers to develop printer 
drivers that print garbage, but 
because it doesn't show, nobody 
cares.  We care however about 
unrecognized tokens, because we 
don't want to inadvertently fax 
out any arbitrary binary file 
(could be an EXE or a ZIP).
Possible values are:
     Tesc    = 
1000
 // ESC

     TescPRCNT       
= 1100
 // ESC %

     TescPAREN       
= 1200
 // ESC (

     TescPARENs      
= 1210
 // ESC ( s

     TescASTRK       
= 1300
 // ESC *

     TescASTRKb      
= 1310
 // ESC * b

     TescASTRKc      
= 1320
 // ESC * c

     TescASTRKp      
= 1330
 // ESC * p

     TescASTRKr      
= 1340
 // ESC * r

     TescASTRKt      
= 1350
 // ESC * t

     TescASTRKv      
= 1360
 // ESC * v

     TescAMPER       
= 1400
 // ESC &

     TescAMPERa      
= 1410
 // ESC & a

     TescAMPERf      
= 1420
 // ESC & f

     TescAMPERl      
= 1430
 // ESC & l

     TescAMPERp      
= 1440
 // ESC & p

     TescAMPERs      
= 1450
 // ESC & s

     TescAMPERd      
= 1460
 // ESC & d

     TescAMPERdD     
= 1461
 // ESC & d # D

     TescAMPERk      
= 1470
 // ESC & k

     TescAMPERkG     
= 1471
 // ESC & k # G

     TescAMPERkS     
= 1472
 // ESC & k # S

     TescPLUS= 
2000
 // ESC +




Appendix B:  Task File
The LanFax Redirector fax server has a 
batch facility which allows batch addition 
of user names and phonebook entries, event 
deletion and automatic delayed shutdown.  
When the server starts, it looks for a 
file called LANFAX.TSK and if found, 
executes the commands in that file.  The 
file must be an ASCII text file.  Once the 
commands are executed, the server deletes 
the file and begins normal operation.
The batch file facility is very powerful 
because commands in the Task file are 
executed before the server enters multi-
tasking mode.  As a result, operations are 
a great deal faster than when executed in 
normal mode.
The file is read in in text mode, i.e. CR, 
CRLF and LF all represent the line 
termination, TAB/SPACE/FF all are ignored. 
Adding Users
To add a user, insert a line of the format
	AUS=Name;Password;Rights
 Add a user to the system, Name will be 
the name converted to uppercase. Password 
will be preserved case sensitive, it can 
be omitted. Rights is the default rights 
mask.
 NOTE: If no password is desired, put one 
space.  DO NOT PUT TWO semicolons ADJACENT 
TO EACH OTHER.
Delayed Shutdown
To request a shutdown at a future time, 
insert the line
	SHU=Hours
This will cause the server to SHUtdown 
(fully automatic) after x Hours.  The 
number of hours can be within the range 
1..65535 giving a maximum of 7 years of 
span.  First level shutdown will commence 
at the given moment of time.  After ten 
minutes OR after last conversion/print job 
(whichever takes more time) has completed, 
second level shutdown will begin.
Normally, server shutdown does not occur 
spontaneously.
Clear An Event
To cancel an event, insert the line
	WIP=Event
This command WIPes out completely the 
given event number.
Add Names to Phonebook
To add entries to the phonebook, insert a 
line of the format
	APB=Name;Company;FaxC;FaxA;FaxN;VoiceC;V
oiceA;VoiceN;BFT
This command adds a name to the PhoneBook. 
All added entries will have the following 
properties:
      - Public
      - Phone numbers (vs Group or IPM)
      - Preferred time: ASAP
      - Revised: today
      - Owner: SUSER
The rest of the properties come from the 
APB line, BFT can be 0 or 1.
NOTE: do not place two semicolons 
adjacent, always insert a space if an 
empty field is desired.


Appendix C:  Database Linkage
The LanFax Redirector fax server maintains 
four databases in Paradox format.  These 
are
	USERS - list of authorized user 
profiles
	PHONE - phone list, group headers, 
IPM addresses
	GROUP - groups of names from within 
phonebook
	AUDIT - the audit trail of fax 
activity - every completed event
These databases can be manipulated with 
Paradox or with other utilities to manage 
Paradox databases. All databases are 
normalised i.e. there must be no duplicate 
entries in either the primary or secondary 
databases.  While Paradox will allow 
duplicates to be entered, the result on 
the server is unpredictable.   
In the discussion below,  MM = 8000 (or 
32765) and  MP = 32766.  The index fields 
are listed and the cross-linkages 
discussed.
USERS
MBox	Is a SHORT, which must be a 
unique number between 1..MM.  
Numbers 0, (MM+1), (MM+2) are 
reserved for server internal 
use.  If these entries are not 
unique, then the results may be 
unpredictable.  The server will 
create a pseudo-entry for 
itself, its MBox will be (MM+1).  
An empty field: will be filled 
with next available number, but 
the entry will not be visible to 
user profile search commands 
until a MBox (between 1..MM) is 
assigned.

Primary key:	USERS:Name
Secondary key:	USERS:MBox
AUDIT
MBox	Correlates 1:1 to USERS:MBox, 
i.e. whenever a user 
sends/receives a fax/ipm, an 
entry is made bearing his/her 
USERS:MBox
Id	Is a alphanumeric, 8 digits + 
terminating 0, field that 
correlates to archival entries. 
It must be unique.

Primary key:	none
Secondary key:	none
PHONE
Owner	Correlates 1:1 to USERS:MBox, 
i.e. whoever dropped the entry 
in the PB, has his/her 
USERS:MBox stamped at 
PHONE:Owner.
Id	Is a SHORT, which must be unique 
number between 1..MP.
If these entries are not unique, then the 
results may be unpredictable.
The server automatically inserts an entry 
with PHONE:Id=(MP+1) and 
PHONE:Owner=(MM+1). This contains the 
server default phone number values.
Primary key:	PHONE:Name, PHONE:Owner
Secondary key:	PHONE:Id
GROUP
Id	Correlates 1:1 to PHONE:Id, i.e. 
this entry belongs to the PB 
entry that has a matching 
PHONE:Id.
Seq	Is a SHORT, it is used to 
distinguish between multiple 
entries.
Each record has space for eight PHONE-
Records, and when those get used, another 
GROUP-record is allocated.
The GROUP:Seq must be allocated in 
sequential fashion with the range 
0..32767.
M1,	Entries M1..M8 correlate 1:1 to 
PHONE:Id, they
M2...M8	are the actual members of the 
group.
Primary key:	GROUP:Id, GROUP:Seq
  This format is based on the Abstract 
Syntax Notation 1 (International Standard 
8824).  Note, however, that the Alcom 
variation uses little endian 
representation of bits.  That is, the 
least significant bit is the rightmost 
bit.
  0 = false, 1 = true
  The ISO ASN.1 primitive type integer has 
no maximum size.  However, for Alcom's 
purposes, the integer type is fixed to 32 
bits.
  List of 0 or more bits.  Since the 
length field of a transfer record 
indicates how many bytes are in the 
record, the data field of this type is 
prefixed by a byte, indicating how many 
bits of the last byte are to be discarded.
  List of 0 or more bytes.
  Human readable string identifying the 
object (in contrast to an object 
identifier, which is intended for 
consumption by machines).
  This tag allows one abstract syntax to 
refer to something from a different one, 
without having to textually include the 
the other one.
  Ordered list of various types.
  Unordered collection of various types.
  Digits 0,1,2,3,4,5,6,7,8,9
  Includes upper and lower case letters, 
the ten digits, space, left and right 
parenthesis, single quote, plus sign, 
minus sign, dot, comma, slash, colon, 
equals sign, and the question mark.
  Based on ISO 3307.  For example, the 
value 17760704210538.8 represents 
5 minutes, 38.8 seconds after 9 pm on the 
Fourth of July, 1776.

viii

vii

10	Introduction

LanFax Redirector Application Programming 
Reference	179

52	LanFax Redirector Extensions to CAS

56	Alcom's Implementation of ASN.1

112	CAS Program Library for DOS

178	CAS DLL for Windows

210	Appendix A:  Configuration

LanFax Redirector Application Programming 
Reference	209

212	Appendix B:  Task File

LanFax Redirector Application Programming 
Reference	213

218	Appendix C:  Database Linkage

LanFax Redirector Application Programming 
Reference	217


