By accessing LANtastic via its API, you can improve the performance and security of your network
Amin R. Ismail and Rhonda Copley
One of the hottest network products on the market, Artisoft's LANtastic is noted for its ease of setup and use. Less well known is the fact that--via programming--you can access several added features of LANtastic to create your own custom applications utilities. When we expanded our five-node network to 30 nodes at the University of Dayton's Department of Electronic Engineering Technology, we needed additional capabilities not available in the standard release. After considerable research, we discovered the LANtastic API.
With a diverse group of users requiring everything from word processing to CAD, the department was looking for a convenient way to manage faculty and student demands
The Downside of NET
All versions of the LANtastic NOS (network operating system) provide users and network administrators with the NET command. Through a menu-driven interface, the NET command lets you log in and out, make drive and printer connections, manipulate print queues, use E-mail,
and monitor network activity. The NET command provides a command-line interface that the network administrator can use for extra tasks, such as customizing a user's machine to fit the network layout; this is particularly true in dedicated-server-based LANtastic networks. For example, an administrator may create a batch file (or place the following sequence of commands in a user's AUTOEXEC.BAT file) to automatically log in to a server after prompting for a user name and password, then map a network drive and printer to the user's machine, synchronize the time-of-day clock on the user's machine with the server's clock, check for any E-mail messages, and return control to the DOS prompt:
NET LOGIN/wait \\server1 ?"Username: " up arrow "Password:"
NET USE E: \\server1\X-DRIVE
NET USE LPT2 \\server1\@PRINTER
NET CLOCK \\server1
NET POSTBOX
The sequence of commands shown in the code fragments above is extremely slow because the 16-KB
NET.EXE file has to be loaded and executed five times. The performance hit is even greater for more complex batch files with several more NET commands or for batch files that are executed from workstations containing only floppy drives.
The LANtastic API allows you to perform the same tasks that the NET command provides and more. By writing a short (about 1900-byte) assembly language program, you can complete the same sequence of commands shown above in less than a tenth of the time required for execution of a batch file. Additionally, a desirable side effect of writing such customized programs is that the NET commands are now no longer visible to the user and cannot be modified in any way. Several network administrators would like to eliminate or restrict the use of the NET command to prevent users from changing the mapping of network resources. Compiled batch files can be used to hide the sequence of NET commands that do the mapping, but they are slower than customized programs written to do the sam
e job--and they still require the presence of the NET command.
The LANtastic API is by no means limited to providing an alternative to the NET command. You can use it to develop any application program for LANtastic.
About the API
All application programs that interact with the NOS make use of the LANtastic API, a set of NetBIOS-compatible functions and extensions that let you access the NOS services from assembly language or high-level languages such as BASIC and C. The LANtastic API consists of 46 services grouped into two main categories: DOS-compatible function calls and LANtastic NOS-specific extended function calls. The table ``LANtastic API Functions'' lists the available services. You will find a more detailed explanation of each function in Adrian King's book Running LANtastic (Bantam Books, 1991). Because LANtastic is a NetBIOS-compatible operating system, the standard NetBIOS functions are also available using the INT 5Ch interface or the alternative INT 2Ah. All the services liste
d in the table are accessed through INT 21h, and because these functions provide most, if not all, of the capabilities of INT 5Ch, only they will be discussed.
Accessing the NOS Services
To access the NOS services, you pass the function number of the service using register AX. For many functions, register BX serves as an index to multiple pieces of data returned by the function as you will see in the following examples. By convention, most functions set the carry flag on return to indicate an error condition with the error number in register AX. The error codes returned are the standard DOS error codes documented in Microsoft's MS-DOS Programmer's Reference (Microsoft Press, 1991). Except for the carry flags, the contents of unused registers are preserved.
To illustrate the use of a LANtastic API service, consider the listing ``The Log-in Function,'' which contains the code fragment to log in the user JONES having a password of SECRET to the server SERVER1. The log-in function number is 5F81h
. To access the function, you move the number into AX and point to the server, user name, and password information using register ES:DI.
Notice that the log-in string actually contains two ASCIIZ strings: The first is the server name formatted as a network path followed by the user name, and the second contains the user's password. The format of such strings varies according to the type of function being accessed as you will see in subsequent examples. Also note that BL contains an adapter number to allow log-ins to a server connected to a network on another adapter card. It is not necessary to initialize segment register ES if the string is located in the same segment as the code.
It is a good idea to perform error checking after calling a NOS service. For example, in the listing ``The Log-in Function,'' if the carry flag is set on return from the function, register AX should be checked for possible error codes that could be returned if the log-in attempt failed. Failed log-in attempts could oc
cur for several reasons, including the following:
-- The server is off-line (error number 35h).
-- The user's account has expired (error number 4Ah).
-- The user's password has expired (error number 4Bh).
-- The user has logged in too many times (error number 54h).
-- The user is already logged in (error number 55h).
-- An invalid user name or password was entered (error number 56h).
-- Log ins to the server are temporarily disabled (error number 46h).
Other network operations such as mapping resources and setting up printers are usually performed immediately after a log- in. Checking the carry flag and associated error codes lets you trap and recover critical NOS errors before proceeding to the next step of the log-in procedure.
Using C and BASIC
Most high-level languages such as C and BASIC provide access to DOS interrupts, thus giving you direct access to low-level DOS and BIOS services. This is done in exactly the same way as in assembly language; you simpl
y set up the registers according to the requirement of a specific function and then initiate an INT 21h call.
For example, the listing ``Log-in with C'' contains a log-in sequence written in C. You need the header file dos.h to access the int86x function. Also defined in dos.h are the union variable REGS and structure SREGS, which are used to access the CPU registers.
To access function 5F81h (i.e., log in to a server), you must first initialize a log-in string containing the server's name, user name, and password formatted as previously explained. You define the log-in string using a string constant and then assign far pointer *lstrg to it. You set register AX to the function number by assigning the value 0x5F81 to the union variable inregs.x.ax. Similarly, you assign the adapter number to register BL (inregs.h.bl). Register DI (inregs.x.di) is then set to the offset address of the log-in string, and register ES is set to the segment address of the log-in string (using the FP_OFF and FP_SEG ma
cros also defined in dos.h). Finally, you call the int86x function with the INT number (0x21), and the values of the input, output, and segment registers are passed as parameters. The function accesses the DOS service and returns the modified register values in outregs. The carry flag is then checked. If the flag is set, an error message and number is printed out.
The listing ``Log-in with BASIC'' shows the log-in function accessed from BASIC. The include file QB.BI (VBDOS.BI, if you're using Visual Basic for DOS) contains the necessary support for the INTERRUPTx function. The data type RegTypeX defined in the include file allows access to the CPU registers. As in the C program example, the log-in string is first constructed in the proper format and assigned to the variable Lstrg. Registers AX and BX are then set to the function number and adapter number, respectively. A pointer to the string variable is assigned to register DI (offset address) and register ES (the segment address). The INTERRUPTx func
tion is called to access DOS INT 21h with the InRegs and OutRegs variables passed as I/O parameters. The function accesses the service and sets OutRegs to the modified register values. The carry flag is checked by examining the least significant bit of the variable OutRegs.flags; if the flag is set, an error message and number are reported.
Function Examples
Regardless of the type of programming language you use, the LANtastic API functions are all accessed through a low-level call to INT 21h. Even though the rest of the code fragments illustrating the use of the API are implemented in assembly language, it should be easy to adapt them to BASIC, C, or any other language that provides access to INT services.
The process of logging out of a server is similar to logging in. The log-out function (5F82h) need specify only the name of the server in ASCIIZ form. Note that the function 5F88h is also available to log you out of all servers attached to the workstation.
To redirect network resour
ces and cancel redirections, you access NOS functions 5F03h and 5F04h, respectively. For example, the listing ``Redirecting Drive Mappings'' maps drive E to the server's network drive X. To redirect a local DOS device (printer or disk) to a network resource, registers SI and DI must point to ASCIIZ strings that hold the device name and network path. Register CX must be set to 0 for compatibility with the NOS functions. If you redirect a hard drive or a printer, you must set register BL to 4 or 3, respectively. In the listing ``Redirecting Drive Mappings,'' for example, you could redirect LPT2 to the server's @PRINTER resource by changing the value in register BL to 3, changing the LDEVNAME to LPT2, and changing NPATH to point to the redirected resource.
To cancel a redirection, you need specify only the name of the local device that is to be canceled; no other inputs are necessary to the 5F04h function call.
Another function normally accessed in a log-in sequence is the NET CLOCK command. This c
ommand synchronizes the server's clock with the workstation's clock. To accomplish the same task, you can use the program fragment shown in the listing ``Accessing the Network Clock,'' which accesses the NOS Get Server's Time function (5FC0h).
The code shown in the listing first calls the NOS Get Server's Time function to move the server's time and date into a data structure defined as TIMEBLK. Register SI points to the data structure while register DI points to the ASCIIZ server name on input. On return, the TIMEBLK data structure is filled in with the server's date and time. The code then extracts the date information from TIMEBLK and places it in the appropriate registers for the DOS function Set Date (2BH). The code then executes an INT 21h to set the date of the local workstation. Next, the time is extracted from TIMEBLK and placed in the appropriate registers for the DOS Set Time function (2Dh), and again, an INT 21h is executed to set the time of the local machine.
Some NOS services can b
e invoked several times in succession to obtain multiple pieces of information. One such function is Get Queue Entry (5FA0h), which obtains a list of all mail and print queues posted for a particular user on a server. For example, if you spooled two files for printing and sent three mail messages, there would be five queue entries on the server for that user name. Each time the Get Queue Entry function is called, NOS releases information on one of the entries until there are no more.
To accomplish this task, register BX is used as a queue-entry index. When the function is initially called, register BX must be set to 0 to identify the first queue entry. On each subsequent call to the function, BX is automatically incremented to the next entry while a 162-byte buffer pointed to by register ES:DI is filled with the queue information. When register AX returns an error code of 12h (i.e., no more files), there are no more entries, and you can terminate the process. A certain byte (called the Queue type) in t
he information block identifies the entry as a mail or print queue; if desired, this byte can be examined to obtain a count of only the mail queues or print queues.
The listing ``The Mail Subroutine'' shows a subroutine called MAIL that determines how many mail messages exist on a specified server whose ASCIIZ name is pointed to by ES:DI. On entry, ES:DI points to the ASCIIZ server name. On return, register CX contains a count of the mail messages posted on the server.
Within the subroutine, register CX is used to keep track of the number of queue entries being held on the server. Register BX is used as an index into the list of queue entries and is initially set to 0 to allow the Get Queue Entry function to read the first queue entry. If the function returns a 12h (no more entries), then the subroutine terminates with the count in CX. The Get Queue Entry function reads each queue entry into the data structure defined as QUEUE. The byte at OFFSET QTYPE in the data structure identifies the entry
as either a mail message (1) or a printer queue (0). If the entry is a mail entry, then it is counted; otherwise, the entry is ignored. The function automatically increments BX to point to the next queue entry, and the process is repeated. The subroutine will count all mail messages (sent and received) that are posted on the server for a particular user. To be more selective and to count only mail received for a particular user, the QDEST information must be examined.
A detailed explanation of the information block returned by the Get Queue Entry function described in the above subroutine is beyond the scope of the article, but it provides a powerful means of manipulating and examining queues. The book Running LANtastic includes more detailed information on the format of the information blocks returned by this and other similar NOS functions.
Putting It All Together
The LANtastic NOS services examined so far have been sufficient to implement the five NET commands that were used as an example
at the beginning of this article. The sample program LOGIN.ASM integrates these functions and others into a complete assembly language program to perform the following task:
-- Prompt the user for a name and password
-- Map a network drive resource
-- Map a network printer resource
-- Set LPT notification on
-- Set the LPT time-out to 10 seconds
-- List all mail messages received
The program uses two additional functions not discussed earlier: Set Redirected Printer Time-Out (5FD1h) and Set LPT Notification (5F9Eh). To set the LPT time-out value for a redirected printer, the Set Redirected Printer Time-Out function is called with register CX containing the printer time-out in ticks (18.2 ticks = 1 second). A value of 0 in register CX will disable the time-out. No information other than a possible error code is returned. The Set LPT Notification function is called with register DX set to 0 to disable the LPT notification pop-up message when a file has been despooled to the pr
inter or to 80h to enable the pop-up notification message. Like the set time-out function, no information is returned other than a possible error code in AX. After a user logs in, the program lists all mail messages destined to the logged-in user. This is not simply a count of the mail messages, but a list that identifies the sender's name and the comment attached to the mail message. Again, the Get Queue Entry function is used to extract this information but in a different form.
LOGIN.ASM is formatted to be assembled into a .COM file rather than an .EXE file. The resulting .COM file produced is only 1972 bytes in size and executes in a fraction of the time that a batch file takes to execute a sequence of NET commands.
The sample program USERS.BAS, written in Visual Basic for DOS, illustrates the use of the Get Active User Information function (5FB0h) to obtain a list of all user activity on the server. Like the Get Queue Entry function, this service uses the same procedure to obtain information
on all log-in entries to a specified server. The information that this program displays is similar to the Display Server Activity screen in NET. Because of the close compatibility between QuickBasic and Visual Basic for DOS, the program can be easily modified for QuickBasic.
WHOAMI.C is an example of a short program written in C that uses the LANtastic API to display information on the current log-in. The program identifies the name of the machine, the user name, and the server that the workstation is logged in to. This is accomplished by accessing NOS functions 5E00h, 5F83h, and 5F80h, respectively. See the ``Program Listings'' on page 5 for more information about how you can obtain these programs electronically.
With custom applications developed using the API, we found network administration simplified, security improved, and performance enhanced. A tailored environment combining the user's needs and the administrator's concerns proved advantageous to all, increasing overall productivity. Pl
ans for additional nodes are in the works, and user satisfaction remains high.
Listing: The Log-in Function
MOV AX,5F81h ;NOS log-in function#
MOV DI,OFFSET LSTRING ;point to log-in string
MOV BL,0 ;adapter# is 0
INT 21H
JC ERROR ;check for log-in errors
. ;else proceed
.
LSTRING: DB '\\SERVER1\JONES',0,'SECRET',0
Listing: Log-in with C
#include
#include
char far *lstrg = "\\\\server1\\jones\0secret";
union REGS inregs, outregs;
struct SREGS segregs;
int result;
main()
{
inregs.x.ax = 0x5F81;
inregs.h.bl = 0;
inregs.x.di = FP_OFF(lstrg);
segregs.es = FP_SEG(lstrg);
result = int86x(0x21, &inregs, &outregs, &segregs);
if (outregs.x.cflag)
printf("Network error %d\n", result);
else
printf("Login
Okay");
}
Listing: Log-in with BASIC
` $INCLUDE: 'QB.BI'
COMMON SHARED InRegs AS RegTypeX, OutRegs AS RegTypeX
DIM Lstrg AS STRING * 50
Lstrg = "\\SERVER1\JONES" + CHR$(0) + "SECRET" + CHR$(0)
InRegs.ax = &H5F81
InRegs.bx = 0
InRegs.es = VARSEG(Lstrg)
InRegs.di = VARPTR(Lstrg)
INTERRUPTx &H21, InRegs, OutRegs
IF OutRegs.flags AND 1 THEN
PRINT "Network error"; OutRegs.ax
ELSE
PRINT "Login Okay"
END IF
Listing: Redirecting Drive Mappings
MOV AX,5F03h ;NOS redirect function#
MOV BL,4 ;type of device 4 = disk
MOV CX,0 ;must be 0
MOV SI,OFFSET LDEVNAME ;name of local device
MOV DI,OFFSET NPATh ;redirected network path
INT 21H
JC ERROR ;check for redirect error
. ;else proceed
.
LDEVNAME: DB 'E:',0 NPATH: DB '\\SERVER1\X-DRIVE',0
Listing: Accessing the Network Clock
SETTIM:MOV AX,5FC0h ;get server's time
MOV SI, OFFSET TIMEBLK ;data structure to receive time
MOV DI, OFFSET SRVZ ;point to server1
INT 21h
JC ERROR ;NOS error
MOV SI, OFFSET TIMEBLK ;set pointer to data
MOV CX, WORD PTR[SI] ;get date into CX
INC SI ;point to day
INC SI
MOV DL,[SI] ;get day into DL
INC SI ;point to month
MOV DH,[SI] ;get month into DH
PUSh SI ;save pointer
MOV AH,2BH ;DOS set system date function
INT 21H
CMP AL,0FFH ;see if error
JZ ERROR ;DOS error processing
POP SI ;restore pointer
INC SI ;point to minutes
MOV CL,[SI] ;get minutes into CL
INC SI ;point to hours
MOV CH,[SI] ;get hours into CH
INC SI ;point to one-hundredth second
MOV DL,[SI] ;get one-hundredth second into DL
INC SI ;point to seconds
MOV DH,[SI] ;get seconds into DH
MOV AH,2DH ;DOS set system time function
INT 21H
CMP AL,0FFH ;see if error
JZ ERROR ;DOS error processing
. ;continue with program
.
ERROR: ;error-handling code
.
.
;
;time block to receive server's time and date
;
TIMEBLK:
YEAR DW ? ;year
DAY DB ? ;day
MONTh DB ? ;month
MINUTES DB ? ;minutes
HOURS DB ? ;hours
HUND DB ? ;hundredths of a second
SECONDS DB ? ;seconds
SRVZ DB '\\SERVER1',0 ;ASCIIZ server name
Listing: The Mail Subroutine
MAIL:
MOV CX,0 ;count of mail messages
MOV BX,0 ;ind
ex to data
MAIL2:
MOV AX,5FA0h ;get queue-entry function
MOV SI, OFFSET QUEUE ;point to queue data structure
INT 21h ;assume that DI points to the server name
CMP AX,12H ;see if no more entries
JZ QUIT ;quit if so
MOV DI, OFFSET QTYPE ;get QTYPE value
MOV AL,[DI] ;into AL
CMP AL,1 ;see if it's mail queue
JNZ MAIL2 ;bypass rest if not
INC CX ;count the entry
JMP MAIL2 ;continue until done
QUIT: RET
;
; data structure to receive queue entries
;
QUEUE:
QSTATUS DB ? ;status of queue entry
QSIZE DD ? ;size of spooled file
QTYPE DB ? ;type of queue entry
QOUTCON DB ? ;control of despooled file
QCOPIES DW 1 ;num
ber of copies
QSEQ DD ? ;sequence number of entry
QSPFILE DB 48 DUP(?) ;path name of spooled file
QUSER DB 16 DUP(?) ;user name of who spooled file
QMACh DB 16 DUP(?) ;machine name user was on
QDATE DW ? ;date file spooled (DOS format)
QTIME DW ? ;time file spooled (DOS format)
QDEST DB 17 DUP(?) ;ASCIIZ user name/device destination
QCOMM DB 48 DUP(?) ;comment field
Lantastic API Functions
FUNCTION
NUMBER DESCRIPTION NET EQUIVALENT
DOS-compatible calls
5E00h Get Machine Name NET SHOW
5E02h Set Printer Setup*
5E03h Get Printer Setup*
5F02h Get Redirected Device Entry NET SHOW
5F03h Redirect Device NET USE
5F04h Cancel Device Redirection
NET UNUSE
LANtastic NOS extend calls
5F80h Get Log-In Entry NET SHOW
5F81h Log In To A Server NET LOG IN
5F82h Log Out Of A Server NET LOG OUT
5F83h Get User Name Entry NET SHOW
5F84h Get Inactive Server Entry NET SHOW
5F85h Change Password NET CHANGEPW
5F86h Disable Account NET DISABLEA
5F87h Get Account
5F88h Log Out From All Servers NET LOG OUT
5F97h Copy File NET COPY
5F98h Send Unsolicited Message NET SEND
5F99h Get Last Received Unsolicited Message NET RECEIVE
5F9Ah Get Message-Processing Flag
5F9Bh Set Message-Processing Flag
5F9Ch Pop Up Last Received Message NET MESSAGE
5F9Dh Get LPT Notification Fl
ag NET SHOW
5F9Eh Set LPT Notification Flag NET LPT NOTIFY
5FA0h Get Queue Entry NET QUEUE STATUS
5FA1h Set Queue Entry NET QUEUE
5FA2h Control Queue NET QUEUE
5FA3h Get Printer Status
5FA4h Get Stream Information NET STREAM
5FA5h Set Stream Information NET STREAM
5FA7h Create User Audit Entry NET AUDIT
5FB0h Get Active User Information
5FB1h Get Shared Directory Information
5FB2h Get User Name From Account File
5FB3h Translate Path NET EXPAND
5FB4h Create Indirect File NET INDIRECT
5FB5h Get Indirect File Contents
5FC0h Get Server's Time NET CLOCK
5FC8h Schedule Server Shutdown NET SHUTDOWN
5FC9h Canc
el Server Shutdown NET SHUTDOWN
5FCAh Stuff Server Keyboard Buffer NET RUN
5FD0h Get Redirected Printer Time-Out NET SHOW
5FD1h Set Redirected Printer Time-Out NET LPT TIME-OUT
5FE0h Get DOS Service Vector
5FE1h Set DOS Service Vector
5FE2h Get Message Service Vector
5FE3h Set Message Service Vector
* Not supported by LANtastic. However, these calls can be issued, but they don't affect anything. Printer initialization must be done through the NET_MGR program.
Amin R. Ismail is an Associate Professor with the School of Engineering at the University of Dayton. He can be reached on the Internet at
ismail@udavxb.oca.udayton.edu
. or on BIX at
editors@bix.com
. Rhonda Copley is a freelance writer and technical consultant. She can be reached on the Internet or BIX at
editors@bix.com
. Both have worked with LANtastic since its initial release and have set up and maintained networks for several small businesses.