1. Re: IPX network]

--------------7DB87CB4BA3FF8E61801BDDA

argh... patrat has his replyto field set to himself *specifically*
so this message i intended for the listserv was sent to
him only, so, thomas, you'll have 2 copies of this msg

------------begin intended post
> Thomas Parslow wrote:
> How can I get my programs to communicate over a IPX or TCP/IP network?
> If at all possible I would like to do this in Euphoria for DOS
wellllll...
i have 2 different versions of ipx units for dos written in
pascal/asm (actually, i have several units... many even... for
all sorts of ipx/novell/netware/lan/netbios/decnet and file
record locking and NFS stuff and other wierd stuff) that you
or anyone else can take a crack at converting to EU...
these two units, in particular, seemed like the
easiest/best written of the stuff i've got for ipx...

anyways, like i said, anyone wants to take a shot at this
is *more* than welcome to... Rob? Pete? Irv? Dave? Ralf? Jiri?
Carl? Art? (who'd i ferget?)

I had sat down to start converting these units since there
*is* such a high demand for network EU (*pokes rob*) support,
not just tcpip, but file/record locking, ipx, and stuff
for *dos* EU... (i tried to get EUsock to work with dos32lib
and it just wouldnt shoehorn... spent *hours* at it...
dave? jesus? {yeah i fergot you :) greg too :|) but my
pascal is just too rusty, and trueEU sidetracked me :)

so... any takers? comments?

attached are the 2 units: ipx.pas and ipxunit.pas

funfun! --Hawke'
--------------7DB87CB4BA3FF8E61801BDDA
 name="Ipx.pas"
Content-Disposition: inline;
 filename="Ipx.pas"

{
From: greg.miller at shivasys.com

>Could you tell me where to get the ipx units?

I'll post the IPX source here again.  (Perhaps this should go into
the FAQ? :)  There seems to be a big demand for this unit.

{ ipx - IPX communication protocol primitives.          }
unit ipx;

interface uses DOS;

type
     MessageStr          = String;
     IPX_REGS            = Registers;
     Byte4               = array[0..3] of byte;
     NetworkNumber       = Byte4;
     NetworkNode         = array[0..5] of byte;

     ECB                 = record
                            link_address          : Pointer;
                            event_service_routine : Pointer;
                            in_use                : byte;
                            completion_code       : byte;
                            socket_number         : word;
                            ipx_workspace         : Byte4;
                            driver_workspace      : array[0..11] of
byte;
                            immediate_address     : NetworkNode;
                            fragment_count          : word;
                            fragment                : array [0..1] of
record
                                                          address :
pointer;
                                                          length  :
word;
                                                    end;
                           end;

     IPXHEADER           = record
                            checksum              : word;
                            length                : word;
                            transport_control     : byte;
                            packet_type           : byte;
                            dest_network_number   : NetworkNumber;
                            dest_network_node     : NetworkNode;
                            dest_network_socket   : word;
                            source_network_number : NetworkNumber;
                            source_network_node   : NetworkNode;
                            source_network_socket : word;
                           end;

{ ZeroEcb - store zeros in all ecb fields.
 Pre: e is an ECB.
        Post: e is fully zeroed. }
procedure ZeroEcb( var e : ECB );

{ ZeroHeader - Store zeros in all header fields.
 Pre: h is an IPXHEADER.
        Post: h is fulled zeroed. }
procedure ZeroHeader( var h : IPXHEADER );

{ Get1stConnectionNumber - Return first connection number for user name
 Pre: username is valid Novell user name
        Post: Returns first connection number username is logged on or
         0 if not logged on. }
function Get1stConnectionNumber( username : string ) : word;

{ GetInternetAddress - Get the network:node address for a connection.
 Pre: connection_number is valid for a logged on user.
        Post: network_number is valid number of network.
         physical_node is valid station node.
 }
function GetInternetAddress(    connection_number : byte;
                            var network_number : NetworkNumber; {hi:lo}
                            var physical_node : NetworkNode ) : integer;

{ IPXSPXNotLoaded - Executed when ipxspx called but not loaded.
 Pre: IPX not loaded.
        Post: Execution aborted. }
procedure IPXSPXNotLoaded(var NovRegs : Registers);

{ IPXInstalled - Determine if IPX is installed on workstation.
 Pre: Either IPX is or is not installed.
        Post:   If IPX installed initialize global IPXLocation to IPX
entry
         point and return TRUE.
                Otherwise initialize global IPXLocation to
IPXSPXNotLoaded
                entry point and return FALSE.  }
function IPXInstalled : Boolean;

{ IPXSPX - Call ipxspx at address in IPXLocation.
 Pre: IPXInstalled has been called.
         IPX is installed and NovRegs assigned IPX or SPX function
         and parameter values. Not checking is done.
        Post:  IPX or SPX function is called.
         NovRegs assigned by call. }
procedure IPXSPX(var NovRegs:Registers);

{ IPXRelinquishControl - Give ipx momentary control of CPU.
 Pre: IPX loaded.
        Post: IPX execution done. }
procedure IPXRelinquishControl;

{ IPXCancelEvent - Cancels pending event associated with ECB.
            Pre:  e is valid ECB.
                   Post: 00 - Success.
                     F9 - ECB cannot be canceled.
                         FF - ECB not in use. }
function IPXCancelEvent( var e : ECB ) : byte;

{ IPXDisconnectFromTarget - Notify listening node that communications
woth
       specified socket are being terminated.
 Pre: number:node:socket are valid.
        Post: Node notified.   }
procedure IPXDisconnectFromTarget( network_number : NetWorkNumber;
                                   network_node   : NetWorkNode;
                                   network_socket : word );

{ IPXScheduleEvent - Schedule processing of ECB after timer ticks.
 Pre: ticks is number of 18.2 per second ticks.
                e is a valid ECB at the time processing occurs.
        Post: e is processed after timer ticks. }
procedure IPXScheduleEvent( ticks : word; var e : ECB );

{ IPXOpenSocket - Open an application socket.
 Pre: socket to use (BBA-7FFF). All assumed short-lived.
        Post: 00 - Success.
         FE - Socket table full.
                FF - Socket already open.  }
function IPXOpenSocket( socket : word ) : byte;

{ IPXCloseSocket - Close socket. No harm if already closed.
 Pre: socket to close.
        Post: socket is closed. }
procedure IPXCloseSocket( socket : word );

{ IPXListenForPacket - Submit an ECB for use when packet received. Must
                       have ECB available when packet received by IPX.
 Pre: e storage is available when ECB processed by IPX.
         e.socket_number opened.
                e.event_svc-routine valid routine or NULL.
                e.fragment_count normally 2.
                e.fragment[0].address to IPX Header buffer.
                e.fragment[0].length = 30.
                e.fragment[1].address to data area <=546 bytes long.
                e.fragment[1].length = length of data area.
        Post: If socket opened, e is added to pool and return TRUE.
         Otherwise return FALSE.    }
function IPXListenForPacket( var e : ECB ) : Boolean;

{ IPXSendPacket - Send packet using given ECB.
 Pre: e storage is available when ECB processed by IPX.
         e.socket_number opened.
                e.event_svc-routine valid routine or NULL.
                e.immediate_address is address of destination
workstation.
                e.fragment_count normally 2.
                e.fragment[0].address to IPX Header buffer.
                e.fragment[0].length = 30.
                e.fragment[1].address to data area <=546 bytes long.
                e.fragment[1].length = length of data area.
        Post: e.completion_code of: 00 - Message sent.
            FC - Event canceled.
                                        FD - Bad packet.   }

{ IPXGetLocalTarget - Get the bridge address (or node if not bridged)
for
        network:node address.
  Pre: dest_network - network number of workstation.
         dest_node    - network node of workstation.
                dest_socket  - network socket of workstation.
        Post: bridge_address is routing information used by
IPXSendPacket.
         Return 00 - Success.
                       FA - No path to destination. }
function IPXGetLocalTarget( var dest_network   : NetworkNumber;
                            var dest_node      : NetworkNode;
                                dest_socket    : word;
                            var bridge_address : NetworkNode ) : byte;

{ IPXGetIntervalMarker - Return time marker measured in 18.2/sec ticks.
 Pre: None.
        Post: Return time marker. }
function IPXGetIntervalMarker : word;

{ IPXSend -  Send a packet to network:node:socket using send_ecb and
             send_header. send_ecb/send_header should be defined outside of
             IPXSend as both may be in use by ipx after IPXSend completes,
             releasing any local variables.
    Pre: dest_network - network number of destination.
                dest_node    - network node of destination.
                dest_socket  - socket of destination.
                packet_ptr   - pointer to send packet.
  packet_len   - length of send packet
  send_ecb     - ECB to use for sending.
                send_header  - IPXHEADER to use for sending.
                send_socket  - socket to use for sending.
        Post:   If destination reachable, packet is sent. }
procedure IPXSend(  var dest_network   : NetworkNumber;
                    var dest_node      : NetworkNode;
                        dest_socket    : word; { hi:lo }
                        packet_ptr     : Pointer;
                        packet_len     : integer;
                    var send_ecb       : ECB;
                    var send_header    : IPXHEADER;
                     send_socket    : word );

{ IPXReceive - Submit an ECB/header and storage buffer for a received
         message.
    Pre:    receive_ecb    - ECB allocated for recieving.
  receive_header - IPXHEADER allocated for receiving.
                receive_socket - socket to receive on.
 Post: message        - area allocated for received message
            holds data.
                message_size   - size of message area in bytes.
  }
procedure IPXReceive(  var receive_ecb    : ECB;
                       var receive_header : IPXHEADER;
                           receive_socket : word;
                           message        : Pointer;
                           message_size   : word );
{ IPXReceivedFrame - Returns TRUE if message frame received in ECB.
    Pre:    receive_ecb    - ECB allocated for recieving.
 Post: Returns TRUE if message frame received in ECB.
}
function IPXReceivedFrame( receive_ecb : ECB ) : Boolean;


{_________________________________________________________________________}

implementation
   type
     REQUESTBUFFER       = record
                            dest_network_number   : NetWorkNumber;
                            dest_network_node     : NetworkNode;
                            dest_network_socket   : word;
                           end;
     REPLYBUFFER         = record
                            node_address          : NetworkNode;
                           end;
   var IPXLocation : Pointer;              { Address of ipx }

{ abort - Display message and halt.
   Pre:  message is a string. }
procedure abort( message : string );
begin
     writeln( message );
     Halt(1);
end;

{$F+}
{ Get1stConnectionNumber - Return first connection number for user name
 Pre: username is valid Novell user name
        Post: Returns first connection number username is logged on or
         0 if not logged on. }
function Get1stConnectionNumber( username : string ) : word;
var
  NovRegs          : Registers;
  Request          : record
                       len            : Word;
                       buffer_type    : Byte;
                       object_type    : Word;
                       name           : string[47];
                     end;
  Reply            : record
                       len                : Word;
                       number_connections : byte;
                       connection_num     : array[0..99] of byte;
                     end;
begin
  with Request do begin
    len  := 51;
    buffer_type := $15;
    object_type := $0100;
    name := username;
  end;

  Reply.len := 101;     { Maximum number of user connections }

  with NovRegs do begin
    AH := $E3;
    DS := Seg(Request);  {DS:SI points to request}
    SI := Ofs(Request);
    ES := Seg(Reply);    {ES:DI points to reply}
    DI := Ofs(Reply);
    MsDos(NovRegs);

    if (Al <> 0) or (Reply.number_connections = 0)
       then Get1stConnectionNumber := 0
       else Get1stConnectionNumber := Reply.connection_num[0];
  end;
end;

{ GetInternetAddress - Get the network:node address for a connection.
 Pre: connection_number is valid for a logged on user.
        Post: network_number is valid number of network.
         physical_node is valid station node.
 }
function GetInternetAddress(    connection_number : byte;
                            var network_number : NetworkNumber; {hi:lo}
                            var physical_node : NetworkNode ) : integer;
var
  NovRegs          : Registers;
  Request          : record
                       len               : word;
                       buffer_type       : byte;
                       connection_number : byte;
                     end;
  Reply            : record
                       len            : word;
                       network_number : NetworkNumber;
                       physical_node  : NetworkNode;
                       server_socket  : word;
                     end;
begin
  with Request do begin
    len  := 2;
    buffer_type := $13;
  end;
  Request.connection_number := connection_number;
  Reply.len := 12;
  with NovRegs do begin
    AH := $E3;
    DS := Seg(Request);  {DS:SI points to request}
    SI := Ofs(Request);
    ES := Seg(Reply);    {ES:DI points to reply}
    DI := Ofs(Reply);
    MsDos(NovRegs);
    Ah := 0;
    GetInternetAddress := Ax;
  end;
  network_number := Reply.network_number;
  physical_node := Reply.physical_node;
end;

{ IPXSPXNotLoaded - Executed when ipxspx called but not loaded.
 Pre: IPX not loaded.
        Post: Execution aborted. }
procedure IPXSPXNotLoaded(var NovRegs : Registers);
begin
     abort('IPX not loaded');
end;

 { ZeroEcb - store zeros in all ecb fields.
 Pre: e is an ECB.
        Post: e is fully zeroed. }
procedure ZeroEcb( var e : ECB );
var i : byte;
begin
     with e do begin
          link_address := Ptr(0,0);
          event_service_routine := Ptr(0,0);
          in_use := 0;
          completion_code := 0;
          socket_number   := 0;
          for i := 0 to 3 do
              ipx_workspace[i] := 0;
          for i := 0 to 11 do
              driver_workspace[i] := 0;
          for i := 0 to 5 do
              immediate_address[i] := 0;
          fragment_count := 0;
          for i := 0 to 1 do begin
              fragment[i].address := Ptr(0,0);
              fragment[i].length  := 0;
          end;
     end;
end;

{ ZeroHeader - Store zeros in all header fields.
 Pre: h is an IPXHEADER.
        Post: h is fulled zeroed. }
procedure ZeroHeader( var h : IPXHEADER );
var i : byte;
begin
   with h do begin
     checksum              := 0;
     length                := 0;
     transport_control     := 0;
     packet_type           := 0;
     for i := 0 to 3 do
         dest_network_number[i] := 0;
     for i := 0 to 5 do
         dest_network_node[i] := 0;
     dest_network_socket   := 0;
     for i := 0 to 3 do
         source_network_number[i] := 0;
     for i := 0 to 5 do
         source_network_node[i] := 0;
     source_network_socket := 0;
  end;
end;

 { IPXInstalled - Determine if IPX is installed on workstation.
 Pre: Either IPX is or is not installed.
        Post:   If IPX installed initialize global IPXLocation to IPX
entry
         point and return TRUE.
                Otherwise initialize global IPXLocation to
IPXSPXNotLoaded
                entry point and return FALSE.  }
function IPXInstalled : Boolean;
var NovRegs          : IPX_REGS;
begin
  with NovRegs do begin
    AX := $7A00;             {func 7Ah of int 2Fh is used to detect IPX}
    Intr($2F,NovRegs);
    if AL = $FF then begin   {if AL is FFh then IPX is loaded and
available}
      IPXInstalled := TRUE;
      IPXLocation := Ptr(ES,DI); {pointer to IPX entry point in ES:DI}
    end
    else begin
      IPXInstalled := FALSE; {no IPX installed}
      IPXLocation := @IPXSPXNotLoaded;
    end;
  end;
end;

{ IPXSPX - Call ipxspx at address in IPXLocation.
 Pre: IPXInstalled has been called.
         IPX is installed and NovRegs assigned IPX or SPX
function
         and parameter values. Not checking is done.
        Post:  IPX or SPX function is called.
         NovRegs assigned by call. }
procedure IPXSPX(var NovRegs:Registers);
var   Ax_, Bx_, Dx_, Di_, Si_, Es_ : word;
begin
     with NovRegs do begin  { Assign simple variables record field
values }
          Ax_ := Ax;
          Bx_ := Bx;
          Dx_ := Dx;
          Di_ := Di;
          Si_ := Si;
          Es_ := Es;
     end;

     asm                            { Assembler instructions. }
        mov   Ax, Ax_               { Initialize CPU registers.}
        mov   Bx, Bx_
        mov   Dx, Dx_
        mov   Di, Di_
        mov   Si, Si_
        mov   Es, Es_

        push  Bp
        call  dword ptr IPXLocation { Call IPX via address at
IPXLocation. }
        pop   Bp
        mov   Ax_, Ax
        mov   Dx_, Dx
     end;

     NovRegs.Ax := Ax_;             { Return register values to caller }
     NovRegs.Dx := Dx_;
end;

{ IPXRelinquishControl - Give ipx momentary control of CPU.
 Pre: IPX loaded.
        Post: IPX execution done. }
procedure IPXRelinquishControl;
var NovRegs : IPX_REGS;
begin
     with NovRegs do begin
          Bx := $0a;
          IPXSPX(NovRegs);
     end
end;

{ IPXCancelEvent - Cancels pending event associated with ECB.
            Pre:  e is valid ECB.
                   Post: 00 - Success.
                     F9 - ECB cannot be canceled.
                         FF - ECB not in use. }
function IPXCancelEvent( var e : ECB ) : byte;
var NovRegs : IPX_REGS;
begin
     with NovRegs do begin
          Bx := $06;
          ES := Seg(e);    {ES:SI points to ecb}
          SI := Ofs(e);
          IPXSPX(NovRegs);
          IPXCancelEvent := AL;
     end
end;

{ IPXDisconnectFromTarget - Notify listening node that communications
woth
       specified socket are being terminated.
 Pre: number:node:socket are valid.
        Post: Node notified.   }
procedure IPXDisconnectFromTarget( network_number : NetWorkNumber;
                                   network_node   : NetWorkNode;
                                   network_socket : word );
var NovRegs : IPX_REGS;
    request_buffer : REQUESTBUFFER;
begin
     with request_buffer do begin
          dest_network_number := network_number;
          dest_network_node   := network_node;
   dest_network_socket := network_socket;
     end;

     with NovRegs do begin
          Bx := $0B;
          ES := Seg(request_buffer);    {ES:SI points to ecb}
          SI := Ofs(request_buffer);
          IPXSPX(NovRegs);
     end
end;

{ IPXScheduleEvent - Schedule processing of ECB after timer ticks.
 Pre: ticks is number of 18.2 per second ticks.
                e is a valid ECB at the time processing occurs.
        Post: e is processed after timer ticks. }
procedure IPXScheduleEvent( ticks : word; var e : ECB );
var NovRegs : IPX_REGS;
begin
     with NovRegs do begin
          Bx := $05;
          Ax := ticks;
          ES := Seg(e);
          SI := Ofs(e);
          IPXSPX(NovRegs);
     end;
end;

{ IPXOpenSocket - Open an application socket.
 Pre: socket to use (BBA-7FFF). All assumed short-lived.
        Post: 00 - Success.
         FE - Socket table full.
                FF - Socket already open.  }
function IPXOpenSocket( socket : word ) : byte;
var NovRegs : IPX_REGS;
begin
     with NovRegs do begin
          Dx := socket;
          Bx := 0;
          Al := 0;
          IPXSPX(NovRegs);
          Ah := 0;
          IPXOpenSocket := Ax;
     end
end;

{ IPXCloseSocket - Close socket. No harm if already closed.
 Pre: socket to close.
        Post: socket is closed. }
procedure IPXCloseSocket( socket : word );
var NovRegs : IPX_REGS;
begin
     with NovRegs do begin
          Dx := socket;
          Bx := $0001;
          IPXSPX(NovRegs);
     end
end;

 { IPXListenForPacket - Submit an ECB for use when packet received. Must
                       have ECB available when packet received by IPX.
 Pre: e storage is available when ECB processed by IPX.
          e.socket_number opened.
                e.event_svc-routine valid routine or NULL.
                e.fragment_count normally 2.
                e.fragment[0].address to IPX Header buffer.
                e.fragment[0].length = 30.
                e.fragment[1].address to data area <=546 bytes long.
                e.fragment[1].length = length of data area.
        Post: If socket opened, e is added to pool and return TRUE.
         Otherwise return FALSE.    }
function IPXListenForPacket( var e : ECB ) : Boolean;
var NovRegs : IPX_REGS;
begin
     with NovRegs do begin
          BX := $0004;
          ES := Seg(e);    {ES:SI points to ecb}
          SI := Ofs(e);
          IPXSPX(NovRegs);
          IPXListenForPacket := Al = 00;
     end
end;

{ IPXSendPacket - Send packet using given ECB.
 Pre: e storage is available when ECB processed by IPX.
         e.socket_number opened.
                e.event_svc-routine valid routine or NULL.
                e.immediate_address is address of destination
workstation.
                e.fragment_count normally 2.
                e.fragment[0].address to IPX Header buffer.
                e.fragment[0].length = 30.
                e.fragment[1].address to data area <=546 bytes long.
                e.fragment[1].length = length of data area.
        Post: e.completion_code of: 00 - Message sent.
            FC - Event canceled.
                                        FD - Bad packet.   }
procedure IPXSendPacket( var e: ECB );
var NovRegs : IPX_REGS;
begin
     with NovRegs do begin
          ES := Seg(e);    {ES:SI points to ecb}
          SI := Ofs(e);
          BX := $0003;
          IPXSPX(NovRegs);
     end
end;

 { IPXGetLocalTarget - Get the bridge address (or node if not bridged)
for
        network:node address.
  Pre: dest_network - network number of workstation.
         dest_node    - network node of workstation.
                dest_socket  - network socket of workstation.
        Post: bridge_address is routing information used by
IPXSendPacket.
         Return 00 - Success.
                       FA - No path to destination. }
function IPXGetLocalTarget( var dest_network   : NetworkNumber;
                            var dest_node      : NetworkNode;
                                dest_socket    : word;
                            var bridge_address : NetworkNode ) : byte;
var
  NovRegs          : Registers;
  Request          : record
                       network_number    : NetworkNumber;
                       physical_node     : NetworkNode;
                       socket            : word;
                     end;
  Reply            : record
                       local_target      : NetworkNode;
                     end;
begin
     with Request do begin
          network_number := dest_network;
          physical_node := dest_node;
          socket := dest_socket;
     end;
     with NovRegs do begin
          Es := Seg(Request);
          Si := Ofs(Request);
          Di := Ofs(Reply);
          Bx := $0002;
          IPXSPX(NovRegs);
          Ah := 0;
          IPXGetLocalTarget := Ax;
          bridge_address := Reply.local_target;
     end
end;

{ IPXGetIntervalMarker - Return time marker measured in 18.2/sec ticks.
 Pre: None.
        Post: Return time marker. }
function IPXGetIntervalMarker : word;
var
  NovRegs          : Registers;
begin

     with NovRegs do begin
          Bx := $0008;
          IPXSPX(NovRegs);
          IPXGetIntervalMarker := Ax;
     end
end;

 { IPXSend - Send a packet to network:node:socket using send_ecb and
             send_header. send_ecb/send_header should be defined outside
of
             IPXSend as both may be in use by ipx after IPXSend
completes,
             releasing any local variables.
    Pre: dest_network - network number of destination.
                dest_node    - network node of destination.
                dest_socket  - socket of destination.
                packet_ptr   - pointer to send packet.
  packet_len   - length of send packet
  send_ecb     - ECB to use for sending.
                send_header  - IPXHEADER to use for sending.
                send_socket  - socket to use for sending.
        Post:   If destination reachable, packet is sent. }
procedure IPXSend(  var dest_network   : NetworkNumber;
                    var dest_node      : NetworkNode;
                        dest_socket    : word; { hi:lo }
                        packet_ptr     : Pointer;
                        packet_len     : integer;
                    var send_ecb       : ECB;
                    var send_header    : IPXHEADER;
                     send_socket    : word );
begin
     ZeroEcb(send_ecb);
     ZeroHeader(send_header);
     send_ecb.socket_number := send_socket;  { Socket used for sending }
     if IPXGetLocalTarget( dest_network,
           dest_node,
                           dest_socket,
                           send_ecb.immediate_address ) = 0
        then begin
             with send_ecb do begin
                  fragment_count := 2;
                  fragment[0].address := @send_header;
                  fragment[0].length  := sizeof(IPXHEADER);
                  fragment[1].address := packet_ptr;
                  fragment[1].length  := packet_len;
             end;
             with send_header do begin
                  packet_type         := 4;
                  dest_network_number := dest_network;
                  dest_network_node   := dest_node;
                  dest_network_socket := dest_socket;
             end;
             IPXSendPacket( send_ecb );
        end;
end;

 { IPXReceive - Submit an ECB/header and storage buffer for a received
         message.
    Pre:    receive_ecb    - ECB allocated for recieving.
  receive_header - IPXHEADER allocated for receiving.
                receive_socket - socket to receive on.
 Post: message        - area allocated for received message
            holds data.
                message_size   - size of message area in bytes.
  }
procedure IPXReceive(  var receive_ecb    : ECB;
                       var receive_header : IPXHEADER;
                           receive_socket : word;
                           message        : Pointer;
                           message_size   : word );
begin
   ZeroEcb(receive_ecb);
   ZeroHeader(receive_header);
   with receive_ecb do begin
        socket_number := receive_socket; { Socket used for receiving }
        fragment_count := 2;
        fragment[0].address := @receive_header;
        fragment[0].length  := sizeof(IPXHEADER);
        fragment[1].address := message;
        fragment[1].length  := message_size;
   end;
    if not IPXListenForPacket( receive_ecb ) then
     abort('IPX Error - Failure initializing.');
   IPXRelinquishControl;              { Give ipx opportunity to process
}
end;

{ IPXReceivedFrame - Returns TRUE if message frame received in ECB.
    Pre:    receive_ecb    - ECB allocated for recieving.
 Post: Returns TRUE if message frame received in ECB.
}
function IPXReceivedFrame( receive_ecb : ECB ) : Boolean;
begin
 IPXReceivedFrame := (receive_ecb.completion_code = 0) and
                            (receive_ecb.in_use = 0);

end;

begin
end.



--------------7DB87CB4BA3FF8E61801BDDA
 name="Ipxunit.pas"
Content-Disposition: inline;
 filename="Ipxunit.pas"

Unit IpxUnit;



Interface



uses dos;

const

     IPX_PACKET_TYPE    =   4;

type

    NetWrkAdr = record

                  NetworkNumber      : array [1..4] of byte;

                  NodeAddress        : array [1..6]    of byte;

                end;



    IpxHeader = record

                  CheckSum           : word;

                  Len                : word;

                  TransportControl   : byte;

                  PacketType         : byte;

                  Destination        : NetWrkAdr;

                  DestinationSocket  : word;

                  Source             : NetWrkAdr;

                  SourceSocket       : word;

                end;

    ConNbrArr = record

                  Len                : word;

                  Count              : byte;

                  Connections        : array [1..250] of byte;

                end;

    ftype     = record

                  Adr                : pointer;

                  Len                : word;

                end;

    Ecb       = record

                  LinkAddress        : pointer;

                  EventServiceRoutine: pointer;

                  StatusFlag         : byte;

                  CompletionCode     : byte;

                  SocketNumber       : word;

                  WorkSpace          : array [1..4]  of byte;

                  DriverWorkSpace    : array [1..12] of byte;

                  ImmediateAddress   : array [1..6]   of byte;

                  FragmentCount      : word;

                  FragmentDescriptor : array [1..2] of ftype;

                end;

    ConnInfo  = record

                  Len                : word;

                  ObjectID           : array [1..4]  of byte;

                  ObjectType         : word;

                  ObjectName         : array [1..48] of byte;

                  LoginTime          : array [1..7]  of byte;

                  Reserved           : word;

                end;

    NetType   = array [1..4] of byte;

    NodType   = array [1..6]    of byte;

var

   regs           : registers;

   ipxrutofs,

   ipxrutseg      : word;

{-----------------------------------------------------------------------------}

function LeadingZero(w:word) : String;

function Time : String;

procedure WriteHexByte(b : byte);



function  IpxPresent : boolean;

procedure IpxServicesCall;

function  IpxCreateSocket (Socket : word) : boolean;

function  LocalConnectionNumber : byte;

procedure IpxDeleteSocket (Socket : word);

procedure GetInternetAddress (ConnectionNbr : byte; var NetNod : NetWrkAdr);

procedure UserInfo (ConnectionNumber: byte; var ConnInfoRec : ConnInfo);

procedure GetConnections (UserName: string; var ConNbrRec : ConNbrArr);

procedure GetLocalTarget(DestNet : NetWrkAdr;

                         DestSock : word; var LocalTarget : NodType );

procedure SendMessage(ConnectionNumber : byte; Message : String);

Procedure IpxSendPacket(var SendEcb : Ecb);

Procedure IpxReadPacket(var ReadEcb : Ecb);



Implementation



{----------------------------------------------------------------------------}

function LeadingZero;

var

   s : String;

begin

     Str(w:0,s);

     if Length(s) = 1 then

        s := '0' + s;

        LeadingZero := s;

end;

{----------------------------------------------------------------------------}

function Time;

var

    h, m, s, hund : Word;

begin

     GetTime(h,m,s,hund);

     Time:=LeadingZero(h)+':'+LeadingZero(m)+':'+LeadingZero(s);

end;

{----------------------------------------------------------------------------}

procedure WriteHexByte;

const

     hexChars : array [0..$F] of Char =

                '0123456789ABCDEF';

begin

     Write(hexChars[b shr 4],

           hexChars[b and $F]);

end;



{----------------------------------------------------------------------------}

function IpxPresent;

const

     MULTIPLEXER  = $2F;

     IPXINSTALLED = $FF;

begin

     regs.ax:=$7A00;

     intr(MULTIPLEXER,regs);

     if (regs.al = IPXINSTALLED) then IpxPresent:=TRUE

                                 else IpxPresent:=FALSE;

end;

{----------------------------------------------------------------------------}

procedure IpxServicesCall;

begin

     intr($7a,regs);

end;

{----------------------------------------------------------------------------}

function IpxCreateSocket;

const

     IPX_CreateSocket = $00;

     PermanentSocket  = $FF;

     TemporarySocket  = $00;

var

   SwapSocket    : word;

begin

     SwapSocket:=swap(Socket);

     regs.al:=TemporarySocket;

     regs.bx:=IPX_CreateSocket;

     regs.dx:=SwapSocket;

     IpxServicesCall;

     if (regs.al = $00) then IpxCreateSocket:=TRUE

                        else IpxCreateSocket:=FALSE;

                        {0FEh Full Socket Table

                         0FFh Socket Already Opened}

end;

{----------------------------------------------------------------------------}

procedure IpxDeleteSocket;

const

     IPX_DeleteSocket             = $01;

var

     SwapSocket    : word;

begin

     SwapSocket:=swap(Socket);

     regs.bx:=IPX_DeleteSocket;

     regs.dx:=SwapSocket;

     IpxServicesCall;

end;

{----------------------------------------------------------------------------}

function LocalConnectionNumber;

const

     GET_CONNECTION_NUMBER = $DC;

begin

     regs.ah:=GET_CONNECTION_NUMBER;

     regs.al:=$00;

     msdos(regs);

     LocalConnectionNumber:=regs.al;

end;

{----------------------------------------------------------------------------}

procedure  GetInternetAddress;

const

     GET_INTERNET_ADDRESS = $13;

     NETWARE_SERVICE_E3   = $E3;



var

   ReqBlk   : record

                Len       :  word;

                ReqType   :  byte;

                ConnNbr   :  byte;

              end;

   ResBlk   : record

                Len       :  word;

                NetNod    :  NetWrkAdr;

                SrvSocket :  word;

              end;

begin

     with ReqBlk do

       begin

            Len:=sizeof(ReqBlk) - sizeof(Len);

            ReqType:=GET_INTERNET_ADDRESS;

            ConnNbr:=ConnectionNbr;

       end;



     with ResBlk do Len:=sizeof(ResBlk) - sizeof(Len);



     regs.ah:=NETWARE_SERVICE_E3;

     regs.ds:=seg(ReqBlk); regs.si:=ofs(ReqBlk);

     regs.es:=seg(ResBlk); regs.di:=ofs(ResBlk);

     msdos(regs);

     if regs.al <> $00 then writeln('Error GETINTERNETADDRESS...')

     else

       begin

            NetNod.NetworkNumber:=ResBlk.NetNod.NetworkNumber;

            NetNod.NodeAddress:=  ResBlk.NetNod.NodeAddress;

       end;

end;

{----------------------------------------------------------------------------}

procedure UserInfo;

const

     GET_CONNECTION_INFORMATION   = $16;

     NETWARE_SERVICE_E3           = $E3;

var

   ReqBlk   :  record

                Len    :  word;

                ReqType   :  byte;

                ConnNbr   :  byte;

               end;

begin

     with ReqBlk do

       begin

            Len :=sizeof(ReqBlk) - sizeof(Len);

            ReqType:=GET_CONNECTION_INFORMATION;

            ConnNbr:=ConnectionNumber;

       end;

     with ConnInfoRec do Len:=sizeof(ConnInfoRec) - sizeof(Len);

     regs.ah:=NETWARE_SERVICE_E3;

     regs.ds:=seg(ReqBlk);       regs.si:=ofs(ReqBlk);

     regs.es:=seg(ConnInfoRec);  regs.di:=ofs(ConnInfoRec);

     msdos(regs);

end;

{----------------------------------------------------------------------------}

procedure GetConnections;

const

     GET_OBJECT_CONNECTION_NUMBERS= $15;

     USER_BINDERY_OBJECT_TYPE     = $0001;

     NETWARE_SERVICE_E3           = $E3;

var

   ReqBlk    :  record

                  Len          : word;

                  RequestType     : byte;

                  ObjectType      : word;

                  NameLength      : byte;

                  Name            : array [1..48] of byte;

                end;

   swapbind  :  word;

   i         :  integer;

begin

     swapbind:=swap(USER_BINDERY_OBJECT_TYPE);

     with ReqBlk do

       begin

            Len:=sizeof(ReqBlk) - sizeof(Len);

            RequestType:=GET_OBJECT_CONNECTION_NUMBERS;

            ObjectType:=SwapBind;

       end;

     ReqBlk.NameLength:=Length(UserName);

     for i:=1 to ReqBlk.NameLength do ReqBlk.Name[i]:=ord(UserName[i]);



     with ConNbrRec do Len:=sizeof(ConNbrRec) - sizeof(Len);

     regs.ah:=NETWARE_SERVICE_E3;

     regs.ds:=seg(ReqBlk);    regs.si:=ofs(ReqBlk);

     regs.es:=seg(ConNbrRec); regs.di:=ofs(ConNbrRec);

     msdos(regs);

     if regs.al <> 0 then ConNbrRec.Count:=0;

end;

{----------------------------------------------------------------------------}

procedure GetLocalTarget;

const

     IPX_GetLocalTarget           = $02;

var

   ReqBlk     :  record

                  Dnetwork  : NetWrkAdr;

                  DSocket   : word;

                 end;

   ResBlk     :  record

                   Ltarget  : NodType;

                 end;

   swapsocket :  word;

begin

     swapsocket:=swap(DestSock);

     ReqBlk.Dnetwork:=DestNet;

     ReqBlk.DSocket :=swapsocket;



     regs.bx:=IPX_GetLocalTarget;

     regs.es:=seg(ReqBlk);

     regs.si:=ofs(ReqBlk);

     regs.di:=ofs(ResBlk);



     IpxServicesCall;



     if regs.al = $00 then LocalTarget:=ResBlk.Ltarget;

                  {0FAh No path to Destination}

end;

{----------------------------------------------------------------------------}

procedure SendMessage;

const

     USER_BINDERY_OBJECT_TYPE     = $0001;

     NETWARE_SERVICE_E1           = $E1;

var

   ReqBlk     :  record

                  Len       : word;

                  Bindery   : word;

                  ConnNbr   : byte;

                  Mlen      : byte;

                  Mens      : array [1..45] of byte;

                 end;

   ResBlk     :  record

                   Len      : word;

                   Filler   : array [1..100] of byte;

                 end;

   i          :  integer;

begin

     with ReqBlk do

        begin

          Bindery:=swap(USER_BINDERY_OBJECT_TYPE);

          ConnNbr:=ConnectionNumber;

          Mlen:=Length(Message);

          Len:=Mlen + 4;

          for i:=1 to Mlen do mens[i]:=ord(message[i]);

        end;



     ResBlk.Len:=$6400;



     regs.ah:=NETWARE_SERVICE_E1;

     regs.ds:=seg(ReqBlk);  regs.si:=ofs(ReqBlk);

     regs.es:=seg(ResBlk);  regs.di:=ofs(ResBlk);

     msdos(regs);

end;



{----------------------------------------------------------------------------}

Procedure IpxSendPacket;

const

     IPX_SendPacket               = $03;

begin

     regs.bx:=IPX_SendPacket;

     regs.es:=Seg(SendEcb);

     regs.si:=Ofs(SendEcb);

     IpxServicesCall;



     while (SendEcb.StatusFlag <> 0) do ;

end;

{----------------------------------------------------------------------------}

Procedure IpxReadPacket;

const

     IPX_ReceivePacket               = $04;

begin

     regs.bx:=IPX_ReceivePacket;

     regs.es:=Seg(ReadEcb);

     regs.si:=Ofs(ReadEcb);

     IpxServicesCall;

     if regs.al <> $00 then

       begin

          writeln('Error Read Packet ');

          WriteHexByte(Regs.al);

       end;

                  {0ffh NonExistant socket}

end;

{----------------------------------------------------------------------------}

{----------------------------------------------------------------------------}

begin

end.



--------------7DB87CB4BA3FF8E61801BDDA--

new topic     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu