[Back to NETWORK SWAG index] [Back to Main SWAG index] [Original]

    {
    ! Name            : NetBios.Pas
    ! Ver             : 0.10
    ! (C) Copyright   :
    ! Author          : Nicolai Wadstr&ouml;m
    ! Type of code    : Turbo Pascal 5.0 Unit
    ! Date            : 1989-10-xx
    !
    !----------------------------------------------------------------------------
    !
    ! Description:
    ! ------------
    ! NetBios interface routines for Turbo Pascal 4.x, 5.x.
    !
    !
    !
    ! History:
    ! --------
    !
    !
    !
    !
    !============================================================================
    }
    {$A+ Align data + = Word, - = Byte}
    {$B- Boolean evaluation + = complete, - = short-circuit}
    {$D+ Debug info + = On, - = Off}
    {$E- 8087 emulator + = On, - = Off}
    {$F- Force far calls + = On, - = Off}
    {$I+ IO check + = On, - = Off}
    {$L+ Local symbol info + = On, - = Off}
    {$N- 8087 code generation + = On, - = Off}
    {$O+ Overlay code generation + = On, - = Off}
    {$R- Range checking + = On, - = Off}
    {$S+ Stack checking + = On, - = Off}
    {$V- Var-String checking + = On, - = Off}

    Unit NetBios;
    interface

    Uses Dos;

    Const
     {
     ! NetBios commands:
     }
     NetBiosCmd_Call           = $10;
     NetBiosCmd_Listen         = $11;
     NetBiosCmd_HangUp         = $12;

     NetBiosCmd_Send           = $14;
     NetBiosCmd_Rec            = $15;
     NetBiosCmd_RecAny         = $16;
     NetBiosCmd_SendChain      = $17;

     NetBiosCmd_SendDatagram   = $20;
     NetBiosCmd_RecDatagram    = $21;
     NetBiosCmd_SendBroadcast  = $22;
     NetBiosCmd_RecBroadcast   = $23;

     NetBiosCmd_AddName        = $30;
     NetBiosCmd_DeleteName     = $31;
     NetBiosCmd_Reset          = $32;
     NetBiosCmd_AdapterStat    = $33;
     NetBiosCmd_SessionStat    = $34;
     NetBiosCmd_Cancel         = $35;
     NetBiosCmd_AddGroupName   = $36;

     NetBiosCmd_Unlink         = $70;
     NetBiosCmd_SendNoAck      = $71;
     NetBiosCmd_SendChainNoAck = $72;
     NetBiosCmd_FindName       = $78;
     NetBiosCmd_TokenRingTrace = $79;

     NetBiosCmdNoWait         = $80;

     {
     ! NetBios error codes:
     }

     NetBios_Ok               = $00;
     NetBios_IllegalBufLen    = $01;
     NetBios_InvalidCmd       = $03;
     NetBios_Timeout          = $05;
     NetBios_MsgIncomplete    = $06;
     NetBios_InvalidSessionNr = $08;
     NetBios_OutofResources   = $09;
     NetBios_SessionClosed    = $0A;
     NetBios_CmdCanceled      = $0B;
     NetBios_DupLocalName     = $0D;
     NetBios_NameTableFull    = $0E;
     NetBios_Name_Deleted     = $0F;
     NetBios_SessionTableFull = $11;
     NetBios_RemNotListning   = $12;
     NetBios_IvalidNameNr     = $13;
     NetBios_NameNotFound     = $14;
     NetBios_InvalidNameFormat= $15;
     NetBios_NameExists       = $16;
     NetBios_NameDeleted      = $17;
     NetBios_ConnectionLost   = $18;
     NetBios_DupNetworkName   = $19;
     NetBios_BadPacket        = $1A;
     NetBios_InterfaceBusy    = $21;
     NetBios_TooManyCmds      = $22;
     NetBios_InvalidAdapNr    = $23;
     NetBios_CmdNotCanceled   = $24;
     NetBios_InvalidCancelCmd = $26;
     NetBios_AlreadyDefName   = $30; { Name already defined by another envoirment }
     NetBios_EnvNotDef        = $34; { Envoirment not defined, RESET must be issued}
     NetBios_OutOfSysResource = $35; { Required os resources exhausted, retry later}
     NetBios_MaxAPPLExceeded  = $36; { Max. nr of applications eceeded }
     NetBios_OutOfSAPs        = $37; { There is no SAPs available for NetBIOS}
     NetBios_ResourceNotAvail = $38; { Requested resource(s) not available }
     NetBios_InvalidNCB       = $39; { Invalid NCB address or len don' fit in seg}
     NetBios_Illegal_RESET    = $3A; { Reset May not be issued from a NetBios adapter appendage}
     NetBios_InvalidNCB_DD_ID = $3B; { Invalid DeviceDriver ID, OS/2 only }
     NetBios_LockFailed       = $3C; { NetBios attempted to lock user storage but lock failed }
     NetBios_DDOpenErr        = $3F; { Device driver open error, OS/2 only }
     NetBios_OS2error         = $40; { OS/2 error detected, OS/2 only }
     NetBios_HardwareError    = $FE;
     NetBios_NotCompleted     = $FF;

     NrOfNCBs                 = 2;
     CurrentNCB               : Byte = 1;
     MaxSessions              = 20;
     NrOfNames                = 254;
     NetBiosNoWait            : Boolean = False;

    Type
       Str16                  = String[16];
       NameType               = Array[1..16] of Char;
       NodeAddressType        = Array[1..6] of Byte;
       VersionType            = record
                                 Major          : Byte;
                                 Minor          : Byte;
                                end;

       NameEntryType          = record
                                 Name           : NameType;
                                 NameNumber     : Byte;
                                 NameStatus     : Byte;
                                 {
                                 !                |                         |
                                 ! NameStatus     | Meaning                 |
                                 !  Bin     | Dec |                         |
                                 ! -----421----------------------------------
                                 ! 00000000   (0) | Name add in progress.   |
                                 ! 00000100   (4) | Active name.            |
                                 ! 00000101   (5) | Delete pending.         |
                                 ! 00000110   (6) | Improper duplicate name.|
                                 ! 00000111   (7) | Duplicate name, delete  |
                                 !                | pending.                |
                                 ! ------------------------------------------
                                 }
                                end;

       OneSessionStatusType   = record
                                 LocSessionNr   : Byte;
                                 SessionState   : Byte;
                                 {
                                 !              |                         |
                                 ! SessionState | Meaning                 |
                                 ! ----------------------------------------
                                 !            1 | Session LISTEN pending. |
                                 !            2 | Session CALL pending.   |
                                 !            3 | Session active.         |
                                 !            4 | HANG UP pending.        |
                                 !            5 | HANG UP complete.       |
                                 !            6 | Session aborted.        |
                                 ! ----------------------------------------
                                 }

                                 LocName        : NameType;
                                 RemName        : NameType;
                                 RecCmdsOut     : Byte;
                                 SendCmdsOut    : Byte;
                                end;

       SessionStatusType      = record
                                 SessionNr      : Byte;
                                 NrOfSessions   : Byte;
                                 MessCmdsOut    : Byte;
                                 RecAnyCmdsOut  : Byte;
                                 SessionTable   : Array[1..MaxSessions] of OneSessionStatusType;
                                end;

       SessionStatusPtr       = ^SessionStatusType;

       ExtStatusType          = record
                                 DIR_INIT_ErrCode       : Word;
                                 DIR_OPEN_ADAPErrCode   : Word;
                                 LatestNetworkStatus    : Word;
                                 LatestPCError          : Word; {Contents of AX reg}
                                 LatestOperCommandCode  : Byte;
                                 LatestCCBRetCode       : Byte;

                                 LineErrors             : Word;
                                 InternalErrors         : Word;
                                 BurstErrors            : Word;
                                 ARI_FCI_delimiter      : Word;
                                 Abort_delimiter        : Word;
                                 LostFrameErrors        : Word;
                                 RecCongestion          : Word;
                                 FrameCopiedErrors      : Word;
                                 FreqErrors             : Word;
                                 TokenErrors            : Word;
                                 Reserved               : Word;
                                 DMABusErrors           : Word;
                                 DMAParityErrors        : Word;
                                end;

       AdapterStatusType      = record
                                 NodeAddress    : NodeAddressType;
                                 MajorVersion   : Byte;
                                 {
                                 ! $00 = Version 1.xx
                                 ! $02 = Version 2.xx
                                 ! $03 = Version 3.xx
                                 !
                                 }

                                 PowerOnResult  : Byte;
                                 {
                                 ! Always zero in current versions.
                                 }

                                 AdapterType    : Byte;
                                 {
                                 ! $FF = Token-Ring Network Adapter
                                 ! $FE = PC Network Adapter
                                 !
                                 }
                                 MinorVersion   : Byte;

                                 MinSincePowerUp: Word;
                                 {
                                 ! Minutes since system was powered up.
                                 ! Rolls over to zero when it reaches $FFFF.
                                 }

                                 NrOfCRCErrors  : Word;
                                 {
                                 ! Number of CRC error on received packets.
                                 ! Rolls over to zero when it reaches $FFFF.
                                 }

                                 NrOfAlignErrors:Word;
                                 {
                                 ! Number of alignment errors.
                                 ! Rolls over to zero when it reaches $FFFF.
                                 }

                                 NrOfCollisions : Word;
                                 {
                                 ! Number of transmit collision errors.
                                 ! Rolls over to zero when it reaches $FFFF.
                                 }

                                 NrOfAborted    : Word;
                                 {
                                 ! Number of aborted transmissions.
                                 ! Rolls over to zero when it reaches $FFFF.
                                 }

                                 NrOfTxDPackets : LongInt;
                                 {
                                 ! Number of packets trasmitted.
                                 ! Rolls over to zero when it reaches $FFFFFFFF.
                                 }

                                 NrOfRxDPackets : LongInt;
                                 {
                                 ! Number of packets received.
                                 ! Rolls over to zero when it reaches $FFFFFFFF.
                                 }

                                 NrOfReTxDs     : Word;
                                 {
                                 ! Number of retransmissions.
                                 ! Rolls over to zero when it reaches $FFFF.
                                 }

                                 NrOfEoBufErrs  : Word;
                                 {
                                 ! Number of times receiver was out of buffers.
                                 ! Rolls over to zero when it reaches $FFFF.
                                 }

                                 DLCT1_Timeouts : Word;

                                 DLCTi_Timeouts : Word;

                                 ExtStatusPtr   : ^ExtStatusType;
                                 NrOfNCBsFree   : Word;
                                 NrOfNCBsReseted: Word;
                                 MaxResNCBs     : Word;
                                 {
                                 ! Maximum number of NCBs that can be specified
                                 ! by the RESET command.
                                 }

                                 NrOfTxOutOfBuf : Word;
                                 MaxDatagramSize: Word;
                                 ActSessions    : Word;
                                 {
                                 ! Number of active or pending sessions.
                                 }

                                 NrOfResSessions: Word;
                                 {
                                 ! Number of possible sessions specified in
                                 ! last RESET command.
                                 }

                                 MaxResSessions : Word;
                                 {
                                 ! Maximum number of sessions that can be specified
                                 ! by the RESET command.
                                 }

                                 NetPacketSize  : Word;
                                 {
                                 ! Maximum packet size supported by the network
                                 }

                                 NrOfNames             : Word;
                                 PermanentName         : NameEntryType;
                                 NameTable             : Array[1..NrOfNames] of NameEntryType;
                                end;

       NCB_Type               = record
                                 Command               : Byte;
                                 RetCode               : Byte;
                                 LocSessionNr          : Byte;
                                 NameNr                : Byte;
                                 BufferPtr             : Pointer;
                                 BufferLen             : Word;
                                 Callname              : NameType;
                                 Name                  : NameType;
                                 Rec_TimeOut           : Byte;
                                 Send_TimeOut          : Byte;
                                 User_Int              : Pointer;
                                 Adapter_Num           : Byte;
                                 CmdDone               : Byte;
                                 Reserved              : Array[1..14] of Byte;
                                end;

       NCB_TypePtr            = ^NCB_TypePtr;

       TraceHeaderType        = record
                                 TraceBufferPtr         : Pointer;
                                 TraceBufferLen         : Word;
                                 TraceEntryStart        : Word;
                                 CodeChangeLvl          : Array[8..15] of Byte;
                                 TraceEntryCounterLo    : Word;
                                 TraceEntryCounterHi    : Word;
                                 InternBuffersExhaust   : Word;
                                 InternTxdBufferExhaust : Word;
                                 Reserved               : Array[24..27] of byte;
                                 LastTraceEntry         : Word;
                                 NextTraceEntry         : Word;
                                end;

       TraceEntry             = record
                                 AdapterNum             : Byte;
                                 XMA3270BankID          : Byte;
                                 EntryType              : Byte;
                                 Modifier               : Byte;
                                 TicksSinceLastEntry    : Word;
                                 Data                   : Array[6..31] of Byte;
                                end;

       NetBIOSHardwareHeader  = record
                                 HeaderLength           : Byte;
                                 Delimiter              : Word;
                                 Command                : Byte;
                                 Data1                  : Byte;
                                 Data2                  : Word;
                                 TxCorrelator           : Word;
                                 RespCorrelator         : Word;
                                 DestSessionNr          : Byte;
                                 SrcSessionNr           : Byte;
                                end;

    Var
       LocalAdapterStatus     : AdapterStatusType;
       LocalName              : String[16];

    function Call_NetBios(Var NCB:NCB_Type) : Word;
    {
    ! Calls netbios with a NCB.
    !
    }

    function NetBIOSErrorStr ( ErrorCode : Word ) : String;
    {
    ! NetBIOSErrorStr
    ! ---------------
    !
    ! Returns the error code as a explaining strig.
    !
    !
    }

    function NetBIOSAvailable : Boolean;
    {
    ! NetBIOSAvailable
    ! ----------------
    ! Returns true if NetBIOS interface routines can be found otherwise false.
    !
    }

    procedure Name2Str(Name:NameType; Var Strng:String);

    procedure Str2Name(Strng:String; Var Name:NameType);

    function Reset(Var NCB : NCB_Type) : Word;

    function Cancel(Var NCB : NCB_Type) : Word;

    function GetAdapterStat(
                            Var NCB           : NCB_Type;
                            Var Status        : AdapterStatusType
                           ) : Word;

    function Unlink(Var NCB : NCB_Type) : Word;

    function AddName(Var NCB : NCB_Type) : Word;

    function SendBlock(
                       Var NCB         : NCB_Type;
                       Var Buffer
                      ) : Word;

    implementation

    Var
       NetBiosStatus          : Word;

    function Call_NetBios(Var NCB:NCB_Type) : Word;
    {
    ! Calls netbios with a NCB.
    !
    }
    Var
      Regs        : Registers;
    begin
     Regs.ES:=Seg(NCB);
     Regs.BX:=Ofs(NCB);
      Intr($5C,Regs);

    {$IFDEF DEBUGING}
       WriteLn(' NetBIOS Msg(',NCB.RetCode ,' dec): ',NetBIOSErrorStr(NCB.RetCode) );
    {$ENDIF}

     Call_NetBios:=Regs.AX;
    end;

    function NetBIOSErrorStr ( ErrorCode : Word ) : String;
    {
    ! NetBIOSErrorStr
    ! ---------------
    !
    ! Returns the error code as a explaining strig.
    !
    !
    }
    begin
      Case ErrorCode of
       NetBios_Ok               : NetBIOSErrorStr := 'Ok';
       NetBios_IllegalBufLen    : NetBIOSErrorStr := 'Illegal buffer length';
       NetBios_InvalidCmd       : NetBIOSErrorStr := 'Invalid command';
       NetBios_Timeout          : NetBIOSErrorStr := 'Timeout';
       NetBios_MsgIncomplete    : NetBIOSErrorStr := 'Message incomplete';
       NetBios_InvalidSessionNr : NetBIOSErrorStr := 'Invalid session nr';
       NetBios_OutofResources   : NetBIOSErrorStr := 'Out of resources';
       NetBios_SessionClosed    : NetBIOSErrorStr := 'Session closed';
       NetBios_CmdCanceled      : NetBIOSErrorStr := 'Command canceled';
       NetBios_DupLocalName     : NetBIOSErrorStr := 'Duplicate of Localname';
       NetBios_NameTableFull    : NetBIOSErrorStr := 'Nametable full';
       NetBios_Name_Deleted     : NetBIOSErrorStr := 'Name deleted';
       NetBios_SessionTableFull : NetBIOSErrorStr := 'Session table full';
       NetBios_RemNotListning   : NetBIOSErrorStr := 'Remote not listning';
       NetBios_IvalidNameNr     : NetBIOSErrorStr := 'Ivalid name nr';
       NetBios_NameNotFound     : NetBIOSErrorStr := 'Name not found';
       NetBios_InvalidNameFormat: NetBIOSErrorStr := 'Invalid name format';
       NetBios_NameExists       : NetBIOSErrorStr := 'Name exists';
       NetBios_NameDeleted      : NetBIOSErrorStr := 'Name deleted';
       NetBios_ConnectionLost   : NetBIOSErrorStr := 'Connection lost';
       NetBios_DupNetworkName   : NetBIOSErrorStr := 'Dupliacte network name';
       NetBios_BadPacket        : NetBIOSErrorStr := 'Bad packet';
       NetBios_InterfaceBusy    : NetBIOSErrorStr := 'Busy (Try again)';
       NetBios_TooManyCmds      : NetBIOSErrorStr := 'Too Many Commands';
       NetBios_InvalidAdapNr    : NetBIOSErrorStr := 'Invalid adapter nr';
       NetBios_CmdNotCanceled   : NetBIOSErrorStr := 'Command not canceled';
       NetBios_InvalidCancelCmd : NetBIOSErrorStr := 'Invalid cancel command';
       NetBios_HardwareError    : NetBIOSErrorStr := 'Hardware error';
       NetBios_NotCompleted     : NetBIOSErrorStr := 'Not completed';
      end;
    end;

    procedure Name2Str(Name:NameType; Var Strng:String);
    Var B,B1:Byte;
    begin
     B1:=16;
      Strng:=Name;

     B1 := 16;

     for B:= 16 downto 1 do
      if Name[B]=#0 then B1:=B;

     Strng[0]:=Chr(B1);
    end;

    procedure Str2Name(Strng:String; Var Name:NameType);
    Var
       B,
       StrLen     : Byte;
    begin

      for B:= 1 to 16 do Name[B] := #0;

       StrLen   := Length(Strng);

       if StrLen > 16 then StrLen := 16;

      For B := 1 to StrLen do
       Name[B] := Strng[B];

    end;

    function NetBIOSAvailable : Boolean;
    {
    ! NetBIOSAvailable
    ! ----------------
    ! Returns true if NetBIOS interface routines can be found otherwise false.
    !
    }
    Var
      Regs               : Registers;
      NCB                : NCB_Type;
      VectorTable        : Array[0..255] of LongInt absolute $0000:$0000;

    begin

      if VectorTable[$5C] = 0 then
       begin
        NetBIOSAvailable     := False;
        Exit;
       end;

       FillChar(NCB, SizeOf(NCB), #0 );

      NCB.Command      := $FF;       { Invalid command }

      Regs.ES          := Seg(NCB);
      Regs.BX          := Ofs(NCB);

       Intr($5C,Regs);

     NetBiosAvailable := (NCB.RetCode = NetBios_InvalidCmd);
    end;

    {
    !=============================================================================
    !                          NetBios function calls.
    !
    !-----------------------------------------------------------------------------
    }

    function Reset(Var NCB : NCB_Type) : Word;
    begin
     NCB.Command:=NetBiosCmd_Reset;
     Reset := Call_NetBios(NCB);
    end;

    function Cancel(Var NCB : NCB_Type) : Word;
    begin
     NCB.Command:=NetBiosCmd_Cancel;
     Cancel := Call_NetBios(NCB);
    end;

    function GetAdapterStat(
                            Var NCB           : NCB_Type;
                            Var Status        : AdapterStatusType
                           ) : Word;
    begin
     NCB.Command:=NetBiosCmd_AdapterStat;
      NCB.BufferPtr:= Addr(Status);
      NCB.BufferLen:= SizeOf(Status);
     GetAdapterStat:= Call_NetBios(NCB);
    end;

    function Unlink(Var NCB : NCB_Type) : Word;
    begin
     NCB.Command  := NetBiosCmd_Unlink;
     Unlink       := Call_NetBios(NCB);
    end;

    function AddName(Var NCB : NCB_Type) : Word;
    begin
     NCB.Command:=NetBiosCmd_AddName;
     AddName := Call_NetBios(NCB);
    end;

    function SendBlock(
                       Var NCB         : NCB_Type;
                       Var Buffer
                      ) : Word;
    begin
      NCB.Command     := NetBiosCmd_Send;
      NCB.BufferPtr   := Addr(Buffer);
      SendBlock       := Call_NetBios(NCB);
    end;
    end.

[Back to NETWORK SWAG index] [Back to Main SWAG index] [Original]