home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
progjour
/
1991
/
04
/
netbios.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-05-12
|
9KB
|
222 lines
{*****************************************************************************
** NetBIOS Unit Version 1.2 May 1, 1991 **
** Copyright 1987,1988,1991 by L. Brett Glass, Systems Consultant **
******************************************************************************}
unit NetBIOS; {Object-oriented NetBIOS interface}
{This is the latest incarnation of a unit I've used for many years (and in
many articles and programming projects) to interface to NetBIOS. The latest
version is object-oriented; NCBs are objects and can be imagined to be
performing commands on behalf if your program.}
{$R-} {$S-} {$A-}
interface
const {Codes for NetBIOS commands.
Note that only those commands for which there is a constant
ending in NO_WAIT can be executed with the no-wait option.}
{General}
ADAPTER_RESET= $32;
CANCEL = $35;
ADAPTER_STATUS = $33;
ADAPTER_STATUS_NO_WAIT = $B3;
{Remote boot support}
UNLINK = $70;
{Name support}
ADD_NAME = $30;
ADD_NAME_NO_WAIT = $B0;
ADD_GROUP_NAME = $36;
ADD_GROUP_NAME_NO_WAIT = $B6;
DELETE_NAME = $31;
DELETE_NAME_NO_WAIT = $B1;
{Session support}
CALL = $10;
CALL_NO_WAIT = $90;
LISTEN = $11;
LISTEN_NO_WAIT = $91;
HANG_UP = $12;
HANG_UP_NO_WAIT = $92;
SEND = $14;
SEND_NO_WAIT = $94;
CHAIN_SEND = $17;
CHAIN_SEND_NO_WAIT = $97;
RECEIVE = $15;
RECEIVE_NO_WAIT = $95;
RECEIVE_ANY = $16;
RECEIVE_ANY_NO_WAIT = $96;
SESSION_STATUS = $34;
SESSION_STATUS_NO_WAIT = $B4;
{Datagram support}
SEND_DATAGRAM = $20;
SEND_DATAGRAM_NO_WAIT = $A0;
SEND_BROADCAST_DATAGRAM = $22;
SEND_BROADCAST_DATAGRAM_NO_WAIT = $A2;
RECEIVE_DATAGRAM = $21;
RECEIVE_DATAGRAM_NO_WAIT = $A1;
RECEIVE_BROADCAST_DATAGRAM = $23;
RECEIVE_BROADCAST_DATAGRAM_NO_WAIT = $A3;
INTENTIONAL_BAD_COMMAND = $7F;
const {Return codes}
GOOD_RTN = $00; {Good return}
ILL_LENGTH = $01; {Bad length field}
INVALID_CMD = $03; {Bad command number}
TIMEOUT = $05; {Operation timed out}
MSG_INCOMPLETE = $06; {Not enough space for message}
ILL_SESSION = $08; {Session number was invalid}
NOT_AVAIL = $09; {Adapter out of memory}
SESSION_CLOSED = $0A; {Session closed successfully}
CMD_CANCELLED = $0B; {Command cancelled successfully}
DUP_NAME = $0D; {Name already in local table}
NAME_TABLE_FULL = $0E; {Name table is full}
NAME_STILL_ACTIVE = $0F; {Name deregistered but has active sessions}
SESSION_TABLE_FULL = $11; {No more sessions allowed}
OPEN_REJECTED = $12; {No LISTEN pending on remote}
ILL_NAME_NUMBER = $13; {Name number must match name}
NO_ANSWER = $14; {Call not answered}
ILL_NAME = $15; {Name not found or illegal}
NAME_IN_USE = $16; {Name in use on network}
NAME_DELETED = $17; {Name successfully deleted}
SESSION_ABEND = $18; {Session ended abnormally}
NAME_CONFLICT = $19; {Two names on the net are identical}
ILL_PACKET = $1A; {Packet protocol not recognized}
BUSY = $21; {BIOS re-entrancy error}
TOO_MANY_CMDS = $22; {Too many commands outstanding}
INVALID_ADAPTER = $23; {Invalid number for LAN adapter}
CMPL_DURING_CANCEL = $24; {Command completed before it could be cancelled}
CANNOT_CANCEL = $26; {Command cannot be cancelled}
COMMAND_PENDING = $FF; {Command is pending}
type
AdapterNum = 0..1; {Legal adapter number}
NetName = array [1..16] of Char; {Format of a name used in net operations}
{The following variant record supports the use of the
callName field of an NCB for either a network name or
buffer chaining.}
NameOrBufInfo = record
case Boolean of
FALSE: (name : NetName); {Network name}
TRUE: (nextBufLen : Word; {Length of next buffer in a chain}
nextBufPtr : Pointer) {Pointer to next buffer in a chain}
end;
NCB = object
command, {NetBIOS command}
retcode, {Return code}
lsn, {Local session number}
num : Byte; {Number of a local name}
bufPtr : Pointer; {Pointer to message buffer}
len : Word; {Message buffer length}
callName: {Destination name or info about second}
NameOrBufInfo; {buffer in a CHAIN SEND)}
name : NetName; {Source (local) name}
rto, {Receive timeout in half seconds}
sto : Byte; {Send timeout in half seconds}
post : Pointer; {Interrrupt completion routine address}
lana_num : AdapterNum; {Number of LAN adapter}
cmd_cplt : Byte; {Command complete flag}
reserved : array [1..14] of Byte; {Internal use only}
constructor Init(cmd : Byte); {Constructor}
procedure Submit; {Submit self to NetBIOS}
function ReturnCode : Byte; {Submit self. Return code is function result.}
end;
const
{Masks for jumpers field of StatusBuf record}
W1 = $40; {Mask for W1 jumper on IBM net adapter card (Remote Boot)}
W2 = $80; {Mask for W2 jumper on IBM net adapter card (Reserved)}
NAME_STATUS_MASK = $07; {Mask for reg status of name. Apply to status field
of a LocalName record after ADAPTER_STATUS call}
NAME_PENDING_REG = 1; {Registration pending}
NAME_REGISTERED = 4; {Name is registered}
NAME_DEREGISTERED = 5; {Name now deregistered}
NAME_DUPLICATED = 6; {Name was found to be a duplicate}
NAME_DUP_PENDING_DEREG = 7; {Duplicate name now being deregistered}
NAME_GROUP_MASK = $80; {Mask for group/local bit. Apply to status field
of a LocalName record after ADAPTER_STATUS call}
type
LocalName = record
name : NetName; {The name itself}
num, {The number of the name}
status : Byte; {Status of name. See constants above.}
end;
StatusBuf = record
unitID : array [1..6] of Byte; {Unique ID of hardware board}
jumpers, {Reflects jumper settings for W1 and W2}
postResult, {Result byte from adapter POST}
majorVersion, {Software version number}
minorVersion : Byte;
period, {Error reporting period in minutes}
crcErrors, {CRC errors found}
alignErrors, {Alignment errors found}
collisions, {Collisions found}
aborts : Word; {Aborted transmissions}
succXmt, succRcv : Longint; {Successful transmissions and receptions}
reXmts, {Retransmissions}
overruns : Word; {Adapter buffer overruns}
reserved : array [1..8] of Byte; {For internal use}
freeNCBs, {How many more NCBs can there be?}
configMaxNCBs, {Configured max NCBs}
maxNCBs : Word; {Actual max NCBs}
reserved2 : array [1..4] of Byte;
sessions, {How many sessions in progress or pending}
configMaxSessions, {Configured max sessions}
maxSessions, {Actual max sessions}
maxSessionPacketSize : Word; {Max size of packet sent during a session}
nameCount : Word; {Number of local names}
localNames : array [1..16] of LocalName {Local name table}
end;
function NetBIOSPresent: Boolean;
{Determine if the NETBIOS (or an emulation thereof) is present}
implementation
function NCB.ReturnCode : Byte; assembler;
{Call the NetBIOS with the given NCB. The function returns the
same value that appears in the retCode field of the NCB after
the call. Note that commands issued with the no-wait option and
no interrupt completion routine will return their final result
codes in the cmd_cplt field. Note that since we can't use inline
machine code -- the most efficient solution -- in Turbo 6.0, we
use an "assembler" function here.}
asm
les bx,self {Get the "self pointer" that's passed by all objects}
int 5Ch {Call NetBIOS}
end;
procedure NCB.Submit; assembler;
{Call the NetBIOS with the given NCB. All return codes must
be read from the NCB when using this procedure. This is also
an "assembler" function.}
asm
les bx,self
int 5Ch
end;
constructor NCB.Init(cmd : Byte); {Constructor}
begin {InitNCB}
{Fill the NCB with zeroes, then put the command in the first
byte.}
FillChar(self,SizeOf(self),0);
command := cmd; {Add the command type}
end; {InitNCB}
function NetBIOSPresent : Boolean;
var
netBlock : NCB;
netVec : Pointer absolute $0000:$0170;
begin {NetBIOSPresent}
NetBIOSPresent := FALSE;
if netVec = NIL then {Network can't be there if vector is all zeroes}
Exit;
netBlock.Init(INTENTIONAL_BAD_COMMAND);
{If the network's there, it will recognize a bad command}
NetBIOSPresent := (netBlock.ReturnCode = INVALID_CMD)
end; {NetBIOSPresent}
end.