home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / PASCAL / NWTP04 / NWCONN.PAS < prev    next >
Pascal/Delphi Source File  |  1994-01-01  |  39KB  |  1,187 lines

  1. {$B-,V-,X+}
  2. UNIT nwConn;
  3.  
  4. { nwConn unit as of 931228 / NwTP 0.4 API. (c) 1994, R.Spronk }
  5.  
  6. INTERFACE
  7.  
  8. { Primary Functions:                    Interrupt: comments:
  9.  
  10.   AttachToFileServer                    (F100)
  11. * DetachFromFileServer                  (F101)
  12.   EnterLoginArea                        (F217/0A)
  13. * GetConnectionInformation              (F217/16)
  14. * GetConnectionNumber                   (DC..)
  15. * GetInternetAddress                    (F217/13)
  16. * GetObjectConnectionNumbers            (F217/15)
  17. * GetStationAddress                     (EE..)
  18. - GetStationsLoggedInformation          (F217/05) (5)
  19. - Login                                 (F217/00) (3)
  20. * LoginToFileserver                     (F217/14)  UNencrypted
  21. * LoginEncrToFileserver                 (F217/18)  encrypted
  22. * Logout                                (F219)
  23. * LogoutFromFileServer                  (F102)
  24. - MapUserToStationSet                   (F217/02) (4)
  25.  
  26. * EndOfJob                              (D6)      to be rewritten to F218
  27. * GetConnectionID                       (EF04)
  28.   GetConnectionIDtable                  (EF03)    (6)
  29. * GetDefaultConnectionID                (F002)
  30.   GetDriveConnectionID                  (EF02)
  31.   GetDriveFlag                          (EF01)
  32.   GetDriveHandle                        (EF00)
  33. * GetFileServerName                     (EF04)
  34.   GetNetwareShellVersion                (EA00)
  35.   GetNumberOfLocalDrives                (DB..)
  36. * GetPreferredConnectionID              (F001)
  37. * GetPrimaryConnectionID                (F005)
  38.   GetTaskMode                           (B503)
  39.   GetTaskModePointer                    (B504)
  40.   GetWorkstationEnvironment             (EAxx,xx>00) (2)
  41.   SetEndOfJobStatus                     (BB..)
  42.   SetNetwareErrorMode                   (DD..)
  43. * SetPreferredConnectionID              (F000)
  44.   SetPrimaryConnectionID                (F004)
  45.  
  46.   Secondary Functions:
  47.  
  48.   IsConnectionIDinUse                   (EF03)
  49. * GetUserAtConnection                   (GetConnectionInformation)
  50. * GetObjectLoginControl                 (nwBindry.ReadPropertyValue)
  51.  
  52. Notes: -Only functions marked with a * have been tested; others might work.
  53.        -(2): This function is an extension to EA00 GetNetwareShellVersion.
  54.              A function that returns all returned information from the call
  55.              EAxx,xx>00 is sometimes referred to as GetWShardwareAndOS.
  56.        -(6): This function returns the complete Connection ID table. The
  57.              partial function IsConnectionIDInUse has been moved to the
  58.              secondary function group.
  59.  
  60.        -NOT implemented in this API:
  61.         (3): This function has been replaced by F217/14 LoginToFileServer.
  62.         (4): Replaced by F217/15 GetObjectConnectionNumbers.
  63.         (5): Replaced by F217/16 GetConnectionInformation.
  64.  
  65.        -NW 386 can support up to 250 connections, NW 286 Max 100.
  66.        -Type TconnectionList=array[1..250] of byte (Declared in unit nwMisc)
  67.  
  68. Related functions in other units:
  69. ---------------------------------
  70. SendBroadcastMessage (nwMess) ; sends a message to a list of connections.
  71. }
  72. Uses nwMisc,nwBindry;
  73.  
  74. CONST
  75.   DRIVE_PERMANENT = $01; { Drive permanently assigned to fileserver directory }
  76.   DRIVE_TEMPORARY = $02; { Drive temporary assigned to FS dir. Released by EOJ }
  77.   DRIVE_NETWORK   = $03; { Normal drive mapping }
  78.   DRIVE_LOCAL     = $80; { Drive is local. ! By ORing with one of the above bits,
  79.                            it can be reassigned to a FS directory.                  }
  80.  
  81. Type
  82.   TconnIDTable=Record  { used by getConnectionIDtable }
  83.                SlotInUse       :Byte; { 0=Free, >0 : In use }
  84.                OrderNbr        :Byte;  { 1..8, order of servers in table,
  85.                                          sorted by network/node address.}
  86.                NetWorkNbr      :LongInt;
  87.                PhysNodeAddress :TnodeAddress; { 6 bytes hi-lo }
  88.                SocketNbr       :Word;         { receiving socket on server }
  89.                ReceiveTimeOut  :Word;
  90.                RouterPhysNAddr :TnodeAddress; { 6 bytes hi-lo }
  91.                PacketSeqNbr    :Byte;
  92.                ConnectionNumber:Byte; { this WS is known as connection x by this server,
  93.                                         FF:no connection }
  94.                ConnectionStatus:Byte; { FFh?/0?: connection functioning }
  95.                MaxTimeOut      :Word;
  96.                Filler          :array[1..5] of byte;
  97.                end;
  98.  
  99.   TloginControl=Record
  100.                 AccountDisabled           :boolean;
  101.                 AccountExpirationDate     :NovTimeRec; { dmy valid only }
  102.  
  103.                 MinimumPasswordLength     :byte;
  104.                 PasswordControlFlag       :byte;
  105.                 DaysBetweenPasswordChanges:word;
  106.                 PasswordExpirationDate    :NovTimeRec;
  107.                 LastLoginTime             :NovTimeRec; {dmy, hms valid only }
  108.                 GraceLoginsRemaining      :Byte;
  109.                 MaxGraceLoginsAllowed     :byte;
  110.                 BadLoginCount             :byte;
  111.                 AccountResetTime          :NovTimeRec; {dmy, hms valid only }
  112.                 LastIntruderAdress        :TinterNetworkAdress;
  113.  
  114.                 MaxConcurrentConnections  :byte;
  115.                 LoginTimes                :array[1..42] of byte;
  116.  
  117.                 unknown1                  :byte;
  118.                 unknown2                  :NovTimeRec;
  119.                 end;
  120.  
  121. Var result:word;
  122.  
  123. {BB.. [2.0/2.1/3.x]}
  124. Function SetEndOfJobStatus( EndOfJobFlag: Boolean ):Boolean;
  125. { When this function is called with EndOfJobFlag=False and control is returned
  126.   to the root COMMAND.COM, COMMAND.COM will NOT perform an EOJ action.     }
  127.  
  128. {F218 [2.15c+]}
  129. FUNCTION EndOfJob(All : Boolean):boolean;
  130. { forces an end of job
  131.   If All is TRUE, then ends all jobs, otherwise ends a single job.
  132.   Ending a job unlocks and clears all locked or logged files and records.
  133.   It close all open network and local files and resets error and lock modes.
  134.   It also resets the workstation environment.                               }
  135.  
  136. {F219 [2.15c+]}
  137. Function Logout:boolean;
  138. {logout from all file servers, remains attached to Server, effective EOJ }
  139.  
  140. {DB.. [2.0/2.1/3.x]}
  141. Function GetNumberOfLocalDrives( Var drives:Byte ):Boolean;
  142.  
  143. {DC.. [2.0/2.1/3.x]}
  144. Function GetConnectionNumber(Var ConnectionNbr:byte):boolean;
  145. { returns connection number of requesting WS (1..100) }
  146.  
  147. {DD.. [2.0/2.1/3.x]}
  148. Function SetNetwareErrorMode( errMode:Byte):boolean;
  149. { Sets the shell's handling mode for dealing with netware errors.
  150.   0: default, INT 24 handler 'Abort, Retry, Fail';
  151.   1: a netware error number is returned in AL;
  152.   2: the netware error number is translated to a DOS error number,
  153.      this number is returned.
  154.   An EOJ resets the errormode to 0.                                      }
  155.  
  156. {E3../0A [2.0/2.1/3.x]}
  157. Function EnterLoginArea( LoginSubDirName:String;
  158.                          numberOfLocalDrives:Byte ):boolean;
  159. { Changes the login directory. Used by boot-proms.
  160.   LoginSubDirName contains the name of a sub directory under SYS:LOGIN
  161.   (e.g. 'V330' means login.exe is to be executed in directory SYS:LOGIN\V330)}
  162.  
  163. {F217/13 [2.15c+]}
  164. Function GetInternetAddress( ConnNbr : byte;
  165.                               var NetworkNumber:LongInt; { 4 bytes }
  166.                               var physNodeAddress:TnodeAddress; { 6 bytes }
  167.                               Var socketNumber : Word
  168.                               ):boolean;
  169.  
  170. {F217/14 [2.15c+] UNENCRYPTED}
  171. Function LoginToFileServer( objName:String; objType:word;
  172.                             password : string              ):boolean;
  173.  
  174. {F217/18 [2.15c+] ENCRYPTED}
  175. FUNCTION LoginEncrToFileServer(ObjName: String; ObjType: Word;
  176.                                PassWord: String            ): Boolean;
  177.  
  178. {F217/15 [2.15c+]}
  179. Function GetObjectConnectionNumbers( objName:String; objType:Word;
  180.                                      Var numberOfConnections: Byte;
  181.                                      Var connections: TconnectionList ):boolean;
  182. { returns a list of connectionnumbers where objects of the desired type and
  183.   name are logged in.
  184.   Tconnectionlist is defined as an array[1..100] of byte. Max connections for
  185.   Netware 286 = 100. Netware 386 allows more than 100 connections.
  186.   The NumberofConnections is greater or equal to 0,
  187.   if >0 then connections[1..NumberOfConnections] contains a list of connections. }
  188.  
  189. {F217/16 [2.15c+]}
  190. Function GetConnectionInforMation (ConnectionNbr:byte;
  191.                                    Var objName:String;
  192.                                    Var objType:Word;
  193.                                    Var objId:LongInt;
  194.                                    Var LoginTime:NovTimeRec ):boolean;
  195.  
  196. {EA00 [2.0/2.1/3.x]}
  197. Function GetNetwareShellVersion( Var MajorVersion,MinorVersion,
  198.                                      RevisionLevel :Byte       ):Boolean;
  199. { Returns information about a WS environment. Queries shell.
  200.   See also: GetWorkstationEnvironment                                   }
  201.  
  202. {EAxx,xx>00 [2.0/2.1/3.x]}
  203. Function GetWorkstationEnvironment(Var OStype,OSversion,
  204.                               HardwareType,ShortHWType:String):Boolean;
  205.  
  206. {EE.. [2.0/2.1/3.x]}
  207. FUNCTION GetStationAddress( var physicalNodeAddress: TNodeAddress ):boolean;
  208. { Get the physical station address (6 bytes hi-endian) }
  209.  
  210. {EF00 [2.0/2.1/3.x]}
  211. Function GetDriveHandle( Drive:Byte; Var Handle:Byte ):boolean;
  212. { The call returns a pointer to the shell's Drive Handle Table. (32 bytes)
  213.   (Drives A..Z and temporary drives [\]^_' )
  214.   If a drive has been assigned a directory handle on the file server,
  215.   the handle can be found in the DHT at the position corresponding with the drive letter.}
  216.  
  217. {EF01 [2.0/2.1/3.x]}
  218. Function GetDriveFlag( Drive:Byte; Var Flag:Byte ):Boolean;
  219. { This call returns a pointer to the shell's Drive Flag Table (32 Bytes)
  220.   Each entry indicates a drive's status (permanent,temporary,local,unassigned)
  221.   For further explanation see the DRIVE_xxx constants.}
  222.  
  223. {EF02 [2.0/2.1/3.x]}
  224. Function getDriveConnectionID( Drive:Byte; Var connID:Byte):boolean;
  225. { returns the servernumber (1..8) associated with a drive. }
  226.  
  227. {EF03 [2.0/2.1/3.x]}
  228. Function GetConnectionIDTable( connID: byte ; Var table: TconnIDtable ):boolean;
  229.  
  230. {EF04 [2.0/2.1/3.x]}
  231. Function GetConnectionID( serverName: String; Var connID: byte):boolean;
  232.  
  233. {EF04 [2.0/2.1/3.x]}
  234. Function GetFileServerName( connectionID : byte; var ServerName : string):boolean;
  235. { get name of file server. file server number must be in range [1..8] }
  236.  
  237. {F000 [2.0/2.1/3.x]}
  238. Function SetPreferredConnectionID( connectionID :byte ):boolean;
  239. { The preferred server is the default server to which the request packets are sent.
  240.   Calls are routed to the preferred server. (IF explicitly set!).
  241.   If the preferred server was not set then the requests are routed to
  242.   the server that is attached to the current drive. If the current
  243.   drive is a local drive then the requests will be sent to the primary
  244.   server (mostly the server the shell initially attached to.)            }
  245.  
  246. {F001 [2.0/2.1/3.x]}
  247. Function GetPreferredConnectionID(var connID : byte):boolean;
  248.  
  249. {F002 [2.0/2.1/3.x]}
  250. FUNCTION GetDefaultConnectionID(var connID :byte):boolean;
  251. { Returns the connection ID of the file server to which
  252.   the packets are currently being sent.                                    }
  253.  
  254. {F004 [2.0/2.1/3.x]}
  255. FUNCTION SetPrimaryConnectionID( primaryConnectionID :Byte ):boolean;
  256.  
  257. {F005 [2.0/2.1/3.x]}
  258. FUNCTION GetPrimaryConnectionID(var connID :byte ):boolean;
  259. { returns connection number of default file server (1..8) }
  260.  
  261. {F100 [2.0/2.1/3.x]}
  262. function AttachToFileServer( ConnID : Byte) : Boolean;
  263. { Create an attachment between a server and a workstation }
  264. { Does not Login the workstation }
  265.  
  266. {F101 [2.0/2.1/3.x]}
  267. Function DetachFromFileServer( connectionID:byte ):boolean;
  268. { removes server from shell's server table. Relinquishes the
  269.   fileserver connection number and breaks the connection.         }
  270.  
  271. {F102 [2.0/2.1/3.x]}
  272. Function LogoutFromFileServer(var ConnectionID: byte):boolean;
  273. {logout from one file server}
  274.  
  275.  
  276. {B503: (Shell version >=3.01)}
  277. Function GetTaskMode( Var taskMode:Byte):boolean;
  278.  
  279. {B504: (shell version >=3.01)}
  280. Function GetTaskModePointer( PtaskMode:Pointer ):boolean;
  281.  
  282. {***** secondary Functions, Result variable is not used*******************}
  283.  
  284. {EF03 [2.0/2.1/3.x] secondary Function }
  285. Function IsConnectionIDinUse( connID: byte ):boolean;
  286.  
  287. Function GetUserAtConnection( ConnectionNbr:byte; var username: string):boolean;
  288. {This function provides a short method of obtaining just the USERID.}
  289.  
  290. Function GetEffectiveConnectionID(Var connId:byte):boolean;
  291. {What server are the requests currently sent to? }
  292.  
  293. Function GetObjectLoginControl(ObjName:string; ObjType:word;
  294.                                VAR LoginControlInfo:TloginControl):boolean;
  295.  
  296. IMPLEMENTATION{=============================================================}
  297.  
  298. USES Dos;
  299.  
  300. Var UnitReqBuffer:array[1..576] of byte;
  301.     UnitReplyBuffer:array[1..576] of byte;
  302.     UnitRegs:registers;
  303.  
  304. Procedure F2SystemCall(subf:byte;req_size,rep_size:word);
  305. begin
  306. With UnitRegs
  307.  do begin
  308.     DS := Seg(UnitReqBuffer);  SI := Ofs(UnitReqBuffer);   CX := Req_size;
  309.     ES := Seg(UnitReplyBuffer);DI := Ofs(UnitReplyBuffer); DX := rep_size;
  310.     AH := $F2; AL := subf;
  311.     MSDOS(UnitRegs);
  312.     Result:=al;
  313.     end;
  314. end;
  315.  
  316.  
  317. {F000 [2.0/2.1/3.x]}
  318. Function SetPreferredConnectionID( connectionID :byte ):boolean;
  319. { The preferred server is the default server to which the request
  320.   packets are sent.
  321.   Calls are routed to the preferred server. (IF explicitly set!).
  322.   If the preferred server was not set then the requests are routed to
  323.   the server that is attached to the current drive. If the current
  324.   drive is a local drive then the requests will be sent to the primary
  325.   server (mostly the server the shell initially attached to.)            }
  326. var regs : registers;
  327. begin
  328.  regs.ax := $F000;
  329.  regs.dl := connectionID; { 1..8, 0 to clear }
  330.  msdos(regs);
  331.  result:=0;
  332.  SetPreferredConnectionID:=TRUE;
  333. end;
  334.  
  335. {F004 [2.0/2.1/3.x]}
  336. FUNCTION SetPrimaryConnectionID( primaryConnectionID :Byte ):boolean;
  337. var regs : registers;
  338. begin
  339.  regs.ax := $F004;
  340.  regs.dl := primaryConnectionID; { 1..8, or 0 to clear }
  341.  msdos(regs);
  342.  result:=0;
  343.  SetPrimaryConnectionID:=TRUE;
  344. end;
  345.  
  346. {F005 [2.0/2.1/3.x]}
  347. FUNCTION GetPrimaryConnectionID(var connID :byte ):boolean;
  348. { returns connection number of the primary file server (1..8) }
  349. var regs : registers;
  350. begin
  351.  regs.ax := $F005;
  352.  msdos(regs);
  353.  connID := regs.al;
  354.  result:=0;
  355.  GetPrimaryConnectionID:=((connID>0) and (connID<9))
  356. end;
  357.  
  358. {F002 [2.0/2.1/3.x]}
  359. FUNCTION GetDefaultConnectionID(var connID :byte):boolean;
  360. { Returns the connection ID of the file server to which
  361.   the packets are currently being sent.                                    }
  362. var regs : registers;
  363. begin
  364.  regs.ax := $F002;
  365.  msdos(regs);
  366.  connID := regs.al; { 1..8 }
  367.  result:=0;
  368.  GetDefaultConnectionID:=((connID>0) and (connID<9))
  369. end;
  370.  
  371. {F001 [2.0/2.1/3.x]}
  372. Function GetPreferredConnectionID(var connID : byte):boolean;
  373. var regs : registers;
  374. begin
  375.  regs.ax := $F001;
  376.  msdos(regs);
  377.  connID := regs.al; { 1..8, or 0 if the preferred server was not set }
  378.  { The preferred coneection is reset to 0 by an EOJ. }
  379.  result:=0;
  380.  GetPreferredConnectionID:=((connID>0) and (connID<9))
  381. end;
  382.  
  383.  
  384.  
  385. {EF03 [2.0/2.1/3.x]}
  386. Function GetConnectionIDTable( connID: byte ; Var table: TconnIDtable ):boolean;
  387. Type ptarr=^tarr;
  388.      tarr=array[0..8*32] of byte;
  389. Var regs:registers;
  390. begin
  391. If ((connID<1) or (ConnID>8))
  392.  then Result:=$FF
  393.  else begin
  394.       regs.ax:=$EF03;
  395.       MsDos(regs);
  396.       move( ptarr(Ptr(regs.es,regs.si))^[(connID-1)*32], table, 32 );
  397.       table.socketNbr:=swap(table.socketNbr); { force lo-hi }
  398.       table.NetworkNbr:=Lswap(table.NetworkNbr); { force lo-hi }
  399.       table.ReceiveTimeOut:=swap(table.ReceiveTimeOut); { force lo-hi }
  400.       table.MaxTimeOut:=swap(table.MaxTimeOut); { force lo-hi }
  401.       Result:=$00;
  402.       end;
  403. GetConnectionIDTable:=(Result=0);
  404. end;
  405.  
  406. {EF04 [2.0/2.1/3.x]}
  407. Function GetConnectionID( serverName: String; Var connID: byte):boolean;
  408. var regs       : registers;
  409.     name_table : array [1..8*48] of Byte;
  410.     server     : array [1..8] of string;
  411.     count      : integer;
  412.     p          : ^byte;
  413.     lname      : string;
  414. begin
  415.  lname:=serverName; UpString(lname);
  416.  regs.ax := $EF04;
  417.  msdos(regs);
  418.  result:=regs.AL;
  419.  
  420.  p := ptr(regs.es, regs.si); { pointer to shell's server name table. }
  421.  move(p^,name_table,8*48);
  422. for count := 1 to 8 do server[count] := '';
  423.  { name table 8 entries by 48 decimal chars. Asciiz strings. }
  424. for count := 0 to 7
  425.   do ZstrCopy(server[count+1],name_table[1+ count*48],48);
  426.  
  427. count:=1;
  428. While ((count<9) and (server[count]<>lName))
  429.  do inc(count);
  430. If count=9
  431.  then begin
  432.       Result:=$FF; { server name not found }
  433.       GetConnectionID:=False
  434.       end
  435.  else begin
  436.       connID:=count;
  437.       Result:=$00;
  438.       GetConnectionID:=TRUE;
  439.       end;
  440. end;
  441.  
  442. {EF04 [2.0/2.1/3.x]}
  443. Function GetFileServerName( connectionID : byte; var ServerName : string):boolean;
  444. { get name of file server. file server number must be in range [1..8] }
  445. var regs       : registers;
  446.     name_table : array [1..8*48] of Byte;
  447.     server     : array [1..8] of string;
  448.     count      : integer;
  449.     p          : ^byte;
  450. begin
  451.  regs.ax := $EF04;
  452.  msdos(regs);
  453.  result:=regs.AL;
  454.  
  455.  p := ptr(regs.es, regs.si); { pointer to shell's server name table. }
  456.  move(p^,name_table,8*48);
  457. for count := 1 to 8 do server[count] := '';
  458.  { name table 8 entries by 48 decimal chars. Asciiz strings. }
  459. for count := 0 to 7
  460.   do ZstrCopy(server[count+1],name_table[1+ count*48],48);
  461. if ((connectionID<1) or (connectionID>8))
  462.   then serverName:= server[1]
  463.   else ServerName := server[connectionID];
  464. IF ServerName=''
  465.  then result:=$FF
  466.  else result:=$00;
  467. GetFileServerName:=result=0;
  468. end;
  469.  
  470.  
  471. {F100 [2.0/2.1/3.x]}
  472. function AttachToFileServer( ConnID : Byte) : Boolean;
  473. { Create an attachment between a server and a workstation }
  474. { Does not Login the workstation }
  475. Var NovRegs:Registers;
  476. begin
  477. with NovRegs
  478. do begin
  479.    AX := $F100;
  480.    DL := ConnID;
  481.    MsDos(NovRegs);
  482.    Result := AL;
  483.    end;
  484. AttachToFileServer:=(Result=0);
  485. { possible return codes:
  486.   F8 already attached to server; F9 No free connection slots at server;
  487.   FA no more server slots; FE Server Bindery Locked;
  488.   FF No response from server }
  489. end;
  490.  
  491. {F101 [2.0/2.1/3.x]}
  492. Function DetachFromFileServer( connectionID:byte ):boolean;
  493. { removes server from shell's server table. Relinquishes the
  494.   fileserver connection number and breaks the connection.         }
  495. var regs : registers;
  496. begin
  497.  regs.ax := $F101;
  498.  regs.dl := connectionID; { 1..8 }
  499.  msdos(regs);
  500.  result := regs.al;
  501.  DetachFromFileServer:=(result=0);
  502. { returncodes: 00 successful; FF Connection Doesn't exist }
  503. end;
  504.  
  505. {DC.. [2.0/2.1/3.x]}
  506. Function GetConnectionNumber(Var ConnectionNbr:byte):boolean;
  507. { returns connection number of requesting WS (1..100) }
  508. var regs:Registers;
  509. begin
  510. regs.Ah:=$DC;
  511. MsDos(regs);
  512. ConnectionNbr:=Regs.AL; { logical WS connection # }
  513. { cl= first digit of logical conn #, ch= second digit of conn# }
  514. result:=0;
  515. GetConnectionNumber:=true;
  516. end;
  517.  
  518.  
  519. {F217/16 [2.15c+]}
  520. Function GetConnectionInformation (ConnectionNbr:byte;
  521.                                    Var objName:String;
  522.                                    Var objType:Word;
  523.                                    Var objId:LongInt;
  524.                                    Var LoginTime:NovTimeRec ):boolean;
  525. Var
  526.   I,X            : Integer;
  527.   RequestBuffer  : Record
  528.                    PacketLength : Integer;
  529.                    FunctionVal  : Byte;
  530.                    _ConnectionNo : Byte;  { 1..100, nw286 needs this info }
  531.                    End        ABSOLUTE UnitReqBuffer;
  532.   ReplyBuffer    : Record
  533.                    _objId        :LongInt;  { hi-lo }
  534.                    _ObjType     : word;     { hi-lo }
  535.                    _ObjName     : Array [1..48] of Byte;
  536.                    _LoginTime    : NovTimeRec;
  537.                    Reserved:word;
  538.                    End        ABSOLUTE UnitReplyBuffer;
  539. Begin
  540. With RequestBuffer
  541. Do Begin
  542.    PacketLength := 2;
  543.    FunctionVal := $16;
  544.    _ConnectionNo := ConnectionNbr;
  545.    End;
  546. F2SystemCall($17,SizeOf(requestBuffer),SizeOf(ReplyBuffer));
  547. If Result = 0
  548.  Then Begin
  549.       With ReplyBuffer
  550.       Do Begin
  551.          ZstrCopy(ObjName,_objName,48);
  552.          ObjId:=Lswap(_objId);
  553.          ObjType:=swap(_objType);
  554.          logintime:=_logintime;
  555.          End;
  556.       End;
  557. { patch to have a NIL object return an error. }
  558. if objName='' then result:=$FD; { no_such_connection }
  559. GetConnectionInformation:=(result=0);
  560. End { GetConnectInfo };
  561.  
  562.  
  563.  
  564. {F217/14 [2.15c+,unencrypted]}
  565. Function LoginToFileServer( objName:String; objType:word;
  566.                             password : string             ):boolean;
  567. Var req  :record
  568.           len      :word;
  569.           subFunc  :byte;
  570.           _objType :Word; { hi-lo }
  571.           _objName :String[47]; { asciiz?  }
  572.           _objPassw:String[127]; { allowed to be '' }
  573.           end            ABSOLUTE UnitReqBuffer;
  574. Begin
  575. WITH req
  576. do begin
  577.    len:=SizeOf(req)-2;
  578.    subFunc:=$14;
  579.    _objType:=swap(objType);
  580.    PStrCopy(_objName,objName,47); _objName[47]:=#0; UpString(_objName);
  581.    PStrCopy(_objPassw,password,127); UpString(_objPassw);
  582.    end;
  583. F2SystemCall($17,SizeOf(req),0);
  584. LoginToFileServer:=(result=0)
  585. end;
  586.  
  587.  
  588. {F217/18 [3.x]}
  589. FUNCTION LoginEncrToFileServer(ObjName: String; ObjType: Word; PassWord: String): Boolean;
  590. { assumes the current effective server = the server to login to. }
  591.  
  592.  
  593.    FUNCTION LoginEncrypted(ObjName : String; ObjType : Word; VAR key : TencryptionKey): Boolean;
  594.    VAR req : RECORD
  595.              BufLen  : Word;
  596.              _func   : Byte;
  597.              _key    : TencryptionKey;
  598.              _ObjType: Word;
  599.              _ObjName: String[48];
  600.              End                  ABSOLUTE UnitReqBuffer;
  601.    Begin
  602.    With req
  603.     do Begin
  604.        _func := $18;
  605.        _key  := key;
  606.        _ObjType := Swap(objType);
  607.        PstrCopy(_ObjName,ObjName,48); UpString(_ObjName);
  608.        if ObjName[0]<#48
  609.          then _objName[0]:=objName[0]
  610.          else _objname[0]:=#48;
  611.        BufLen:=ord(_ObjName[0])+12;
  612.        End;
  613.    F2SystemCall($17,SizeOf(req),0);
  614.    LoginEncrypted:=(result=0);
  615.    End;
  616.  
  617. VAR
  618.   key : TencryptionKey;
  619.   ObjId:LongInt;
  620.   _pw:string;
  621.   _lpw:Byte;
  622.  
  623. Begin
  624. UpString(password);
  625. _pw:=password;if _pw[0]>#127 Then _pw[0]:=#127;
  626. _lpw:=length(password);
  627. if _lpw=0 Then _pw:=#0;
  628.  
  629. IF GetEncryptionKey(key)
  630.  Then Begin
  631.       writeln('getencryptionkey: OK');
  632.       IF GetBinderyObjectId(objName,objType,ObjId)
  633.        Then Begin
  634.             EncryptPassword(objId,_pw,key);
  635.             writeln('encryptpassword: OK');
  636.             LoginEncrypted(ObjName, ObjType, key);
  637.             End;
  638.       End
  639.  Else begin
  640.       writeln('Getencryptionkey failed. trying unencrypted login..');
  641.       LoginToFileServer(ObjName, ObjType, Password);
  642.       end;
  643.  
  644. LoginEncrToFileServer:= (result=0);
  645. End;
  646.  
  647.  
  648. {F219 [2.15c+]}
  649. Function Logout:boolean;
  650. {logout from all file servers, remains attached to Server, effective EOJ }
  651. begin
  652.  F2SystemCall($19,0,0);
  653. end;
  654.  
  655.  
  656. {F102 [2.0/2.1/3.x]}
  657. Function LogoutFromFileServer(var ConnectionID: byte):boolean;
  658. {logout from one file server}
  659. var regs : registers;
  660. begin
  661.  regs.ah := $F1;
  662.  regs.al := $02;
  663.  regs.dl := connectionID;
  664.  msdos(regs);
  665.  result:=00;
  666.  LogoutFromFileServer:=True;
  667. end;
  668.  
  669. {EE.. [2.0/2.1/3.x]}
  670. FUNCTION GetStationAddress( var physicalNodeAddress: TNodeAddress ):boolean;
  671. { Get the physical station address (6 bytes hi-endian) }
  672. Var Regs              :Registers;
  673. Begin
  674.  {Get the physical address from the Network Card}
  675.  Regs.Ah := $EE;
  676.  MsDos(Regs);
  677.  result:=Regs.AL;
  678.  {nw node= CX BX AX hi-endian}
  679.  physicalNodeAddress[1]:=Regs.CH;
  680.  physicalNodeAddress[2]:=Regs.CL;
  681.  physicalNodeAddress[3]:=Regs.bh;
  682.  physicalNodeAddress[4]:=Regs.bl;
  683.  physicalNodeAddress[5]:=Regs.ah;
  684.  physicalNodeAddress[6]:=Regs.al;
  685.  result := 0;
  686.  GetStationAddress:=true;
  687. End;
  688.  
  689.  
  690. {F217/13 [2.15c+]}
  691. Function GetInternetAddress( ConnNbr : byte;
  692.                               var NetworkNumber:LongInt; { 4 bytes }
  693.                               var physNodeAddress:TnodeAddress; { 6 bytes }
  694.                               Var socketNumber : Word
  695.                               ):boolean;
  696. Var  Request_buffer : record
  697.                      length      : word;
  698.                      subfunction : byte;
  699.                      connection  : byte;
  700.                      end            ABSOLUTE UnitReqBuffer;
  701.       Reply_Buffer : record
  702.                      network : LongInt; { array [1..4] of byte } { hi-lo }
  703.                      node    : array [1..6] of byte;             { hi-lo }
  704.                      socket  : word; { array [1..2] of byte }    { hi-lo }
  705.                      end            ABSOLUTE UnitReplyBuffer;
  706. BEGIN
  707. With request_buffer
  708. do begin
  709.    length := 2;
  710.    subfunction := $13;
  711.    connection := ConnNbr;
  712.    end;
  713. F2SystemCall($17,SizeOf(request_buffer),SizeOf(Reply_buffer));
  714. if result = 0
  715. then With reply_buffer
  716.       do begin
  717.          NetWorkNumber:=Lswap(network); { force lo-hi }
  718.          move(node,physNodeAddress,6);  { _is_ and stays hi-lo }
  719.          socketNumber:=swap(socket);    { force lo-hi }
  720.          end;
  721. GetInternetAddress:=(result=0);
  722. end;
  723.  
  724. {D6.. [2.0/2.1/3.x]}
  725. FUNCTION EndOfJob(All : Boolean):boolean;
  726. { forces an end of job
  727.   If All is TRUE, then ends all jobs, otherwise ends a single job.
  728.   Ending a job unlocks and clears all locked or logged files and records.
  729.   It close all open network and local files and resets error and lock modes.
  730.   It also resets the workstation environment.                               }
  731. Var NovRegs:Registers;
  732. BEGIN
  733. with NovRegs
  734. do begin
  735.    AH := $D6;
  736.    if All
  737.     then BX := $FFFF
  738.     else BX := $00;
  739.    end;
  740. MsDos(NovRegs);
  741. Result:=$00;
  742. EndOfJob:=True;
  743. end;
  744.  
  745. {$IFDEF NewCalls}
  746.  
  747. {F218 [2.15c+]}
  748. FUNCTION EndOfJob(All : Boolean):boolean;
  749. { forces an end of job
  750.   If All is TRUE, then ends all jobs, otherwise ends a single job.
  751.   Ending a job unlocks and clears all locked or logged files and records.
  752.   It close all open network and local files and resets error and lock modes.
  753.   It also resets the workstation environment.                               }
  754. Var req:record
  755.         len:word;
  756.         _all:word;
  757.         end ABSOLUTE UnitReqBuffer;
  758.    { ERR: unclear how the req buffer should be... }
  759. BEGIN
  760. if All
  761.  then req._all := $FFFF
  762.  else req._all := $0000;
  763. req.len:=2;
  764. F2SystemCall($18,2,0);
  765. Result:=$00;
  766. EndOfJob:=True;
  767. end;
  768.  
  769. {$ENDIF}
  770.  
  771.  
  772. {E3../0A [2.0/2.1/3.x]}
  773. Function EnterLoginArea( LoginSubDirName:String;
  774.                          numberOfLocalDrives:Byte ):boolean;
  775. { Changes the login directory. Used by boot-proms.
  776.   LoginSubDirName contains the name of a sub directory under SYS:LOGIN
  777.   (e.g. 'V330' means login.exe is to be executed in directory SYS:LOGIN\V330)}
  778. Var regs:registers;
  779. Var req  :record
  780.           len:word;
  781.           subFunc:byte;
  782.           _numLocDr:Byte;
  783.           _subDirName:String[255];
  784.           end;
  785.     reply:record
  786.           len:word;
  787.           end;
  788. Begin
  789. WITH req
  790. do begin
  791.    len:=SizeOf(req)-2;
  792.    subFunc:=$0A;
  793.    _numLocDr:=numberOfLocalDrives;
  794.    PstrCopy(_subDirName,LoginSubDirName,255); UpString(_subDirName);
  795.    end;
  796. Reply.len:=$00;
  797. With regs
  798. do begin
  799.    AH:=$E3;
  800.    Ds:=seg(Req);
  801.    si:=ofs(Req);
  802.    Es:=seg(Reply);
  803.    di:=ofs(Reply);
  804.    MsDos(regs);
  805.    result:=AL;
  806.    end;
  807. EnterLoginArea:=(result=0)
  808. end;
  809.  
  810. {F217/15 [2.15c+]}
  811. Function GetObjectConnectionNumbers( objName:String; objType:Word;
  812.                                      Var numberOfConnections: Byte;
  813.                                      Var connections: TconnectionList ):boolean;
  814. { returns a list of connectionnumbers where objects of the desired type and
  815.   name are logged in.
  816.   Tconnectionlist is defined as an array[1..100] of byte. Max connections for
  817.   Netware 286 = 100. Netware 386 allows more than 100 connections.
  818.   If you pass a bad Objectname or the object is not logged in, the errorcode
  819.   is NOT set to NO_SUCH_OBJECT ($FC), but GetObjectConnectionNumbers returns 0.}
  820. Var req  :record
  821.           len:word;
  822.           subFunc:byte;
  823.           _objType:Word; { hi-lo}
  824.           _objName:String[47];
  825.           end               ABSOLUTE UnitReqBuffer;
  826.     reply:record
  827.           _NbrOfConn:Byte;
  828.           _connList:TconnectionList
  829.           end               ABSOLUTE UnitReplyBuffer;
  830. Begin
  831. WITH req
  832. do begin
  833.    len:=SizeOf(req)-2;
  834.    subFunc:=$15;
  835.    PstrCopy(_objName,objName,47); _objname[47]:=#0; UpString(_objName);
  836.    _objType:=swap(objType);
  837.    end;
  838. F2SystemCall($17,SizeOf(req),SizeOf(reply));
  839. With reply
  840. do begin
  841.    connections:=_connList;
  842.    NumberOfConnections:=_NbrOfConn;
  843.    end;
  844. getObjectConnectionNumbers:=(result=0)
  845. end;
  846.  
  847. {EF00 [2.0/2.1/3.x]}
  848. Function GetDriveHandle( Drive:Byte; Var Handle:Byte ):boolean;
  849. { The call returns a pointer to the shell's Drive Handle Table. (32 bytes)
  850.   (Drives A..Z and temporary drives [\]^_' )
  851.   If a drive has been assigned a directory handle on the file server,
  852.   the handle can be found in the DHT at the position corresponding with the drive letter.}
  853. Type pArr=^arr;
  854.      arr=array[0..31] of byte;
  855. Var regs:registers;
  856.     Udrive:char;
  857. begin
  858. regs.ax:=$EF00;
  859. MsDos(regs);
  860. if Drive>31
  861.  then result:=$0105
  862.  else begin
  863.       Handle:=Parr(Ptr(Regs.Es,Regs.Si))^[Drive];
  864.       Result:=0;
  865.       end;
  866. GetDriveHandle:=(Result=0);
  867. end;
  868.  
  869. {EF01 [2.0/2.1/3.x]}
  870. Function GetDriveFlag( Drive:Byte; Var Flag:Byte ):Boolean;
  871. { This call returns a pointer to the shell's Drive Flag Table (32 Bytes)
  872.   Each entry indicates a drive's status (permanent,temporary,local,unassigned)
  873.   For further explanation see the DRIVE_xxx constants.}
  874. Type pArr=^arr;
  875.      arr=array[0..31] of byte;
  876. Var regs:registers;
  877. begin
  878. regs.ax:=$EF01;
  879. MsDos(Regs);
  880. If Drive>31
  881.   then result:=$0105
  882.   else begin
  883.        Flag:=Parr(Ptr(Regs.es,regs.si))^[Drive];
  884.        Result:=0;
  885.        end;
  886. GetDriveFlag:=(Result=0);
  887. end;
  888.  
  889. {EF02 [2.0/2.1/3.x]}
  890. Function getDriveConnectionID( Drive:Byte; Var connID:Byte):boolean;
  891. { returns the servernumber (1..8) associated with a drive. }
  892. Type pArr=^arr;
  893.      arr=array[0..31] of byte;
  894. Var regs:registers;
  895. begin
  896. regs.ax:=$EF02;
  897. MsDos(Regs);
  898. If Drive>31
  899.  then result:=$0105
  900.  else begin
  901.       connID:=Parr(Ptr(Regs.es,regs.si))^[Drive];
  902.       Result:=0;
  903.       end;
  904. GetDriveConnectionID:=(Result=0);
  905. end;
  906.  
  907. {EA00 [2.0/2.1/3.x]}
  908. Function GetNetwareShellVersion( Var MajorVersion,MinorVersion,
  909.                                      RevisionLevel :Byte       ):Boolean;
  910. { Returns information about a WS environment. Queries shell.
  911.   See also: GetWorkstationEnvironment                                   }
  912. Var regs:Registers;
  913.     reply:record
  914.           stringz4:array[1..4*32] of byte;
  915.           end;
  916. Begin
  917. With regs
  918. do begin
  919.    AX:=$EA00;
  920.    ES:=seg(reply);
  921.    DI:=ofs(reply);
  922.    MsDos(regs);
  923.    MajorVersion:=BH;
  924.    MinorVersion:=BL;
  925.    { shell version>=3.00 : }
  926.    { CH = Shell Type. 0=conventional, 1= expanded, 2= extended }
  927.    RevisionLevel:=CL; { 1=A,2=B etc. }
  928.    end;
  929. Result:=$00;
  930. GetNetwareShellVersion:=True;
  931. end;
  932.  
  933. {EAxx,xx>00 [2.0/2.1/3.x] (shell version >=3.00) }
  934. Function GetWorkstationEnvironment(Var OStype,OSversion,
  935.                               HardwareType,ShortHWType:String):Boolean;
  936. Var regs:Registers;
  937.     reply:record
  938.           stringz4:array[1..4*32] of char;
  939.           end;
  940.     sNo,k:Byte;
  941. Begin
  942. With regs
  943. do begin
  944.    AX:=$EA01;
  945.    BX:=$00;
  946.    ES:=seg(reply);
  947.    DI:=ofs(reply);
  948.    MsDos(regs);
  949.    end;
  950. OStype:='';
  951. OSVersion:='';
  952. HardwareType:='';
  953. ShortHWtype:='';
  954. sNo:=0;k:=0;
  955. With reply
  956. do begin
  957.    while sNo<4
  958.    do begin
  959.       inc(k);
  960.       while ((k<128) and (stringz4[k]<>#0))
  961.       do begin
  962.          Case sNo of
  963.           0:OStype:=OStype+stringz4[k];
  964.           1:OSversion:=OSversion+stringz4[k];
  965.           2:HardwareType:=HardwareType+stringz4[k];
  966.           3:ShortHWtype:=ShortHWtype+stringz4[k];
  967.          end; {case}
  968.          inc(k);
  969.          end;
  970.       inc(Sno);
  971.       end;
  972.    end;
  973. Result:=$00;
  974. GetWorkstationEnvironment:=True;
  975. end;
  976.  
  977. {DD.. [2.0/2.1/3.x]}
  978. Function SetNetwareErrorMode( errMode:Byte):boolean;
  979. { Sets the shell's handling mode for dealing with netware errors.
  980.   0: default, INT 24 handler 'Abort, Retry, Fail';
  981.   1: a netware error number is returned in AL;
  982.   2: the netware error number is translated to a DOS error number,
  983.      this number is returned.
  984.   An EOJ resets the errormode to 0.                                      }
  985. Var regs:registers;
  986. begin
  987. Regs.AH:=$DD;
  988. Regs.DL:=errMode;
  989. MsDos(Regs);
  990. { regs.al now contains previous error mode }
  991. Result:=$00;
  992. SetNetWareErrorMode:=True;
  993. end;
  994.  
  995. {BB.. [2.0/2.1/3.x]}
  996. Function SetEndOfJobStatus( EndOfJobFlag: Boolean ):Boolean;
  997. { When this function is called with EndOfJobFlag=False and control is returned
  998.   to the root COMMAND.COM, COMMAND.COM will NOT perform an EOJ action.     }
  999. Var regs:Registers;
  1000. begin
  1001. regs.AH:=$BB;
  1002. If EndOfJobFlag
  1003.  then regs.AL:=$01
  1004.  else regs.AL:=$00;
  1005. MsDos(Regs);
  1006. { AL now contains previous EOJ Flag }
  1007. Result:=$00;
  1008. SetEndOfJobStatus:=True;
  1009. end;
  1010.  
  1011. {DB.. [2.0/2.1/3.x]}
  1012. Function GetNumberOfLocalDrives( Var drives:Byte ):Boolean;
  1013. Var regs:registers;
  1014. begin
  1015. regs.ah:=$DB;
  1016. MsDos(Regs);
  1017. drives:=Regs.AL;
  1018. Result:=$00;
  1019. GetNumberOfLocalDrives:=TRUE;
  1020. end;
  1021.  
  1022. {B503: (Shell version >=3.01)}
  1023. Function GetTaskMode( Var taskMode:Byte):boolean;
  1024. Var regs:registers;
  1025. begin
  1026. Regs.AX:=$B503;
  1027. MsDos(Regs);
  1028. taskMode:=Regs.AL;
  1029. result:=0;
  1030. GetTaskMode:=TRUE;
  1031. end;
  1032.  
  1033. {B504: (shell version >=3.01)}
  1034. Function GetTaskModePointer( PtaskMode:Pointer ):boolean;
  1035. Var Regs:Registers;
  1036. begin
  1037. Regs.AX:=$B504;
  1038. MsDos(regs);
  1039. PtaskMode:=Ptr(regs.ES,regs.BX);
  1040. result:=0;
  1041. GetTaskModePointer:=TRUE;
  1042. end;
  1043.  
  1044. {=======SECONDARY FUNCTIONS===================================================}
  1045.  
  1046. {
  1047. Function template(   ):boolean;
  1048. Var regs:registers;
  1049. Var req  :record
  1050.           len:word;
  1051.           subFunc:byte;
  1052.  
  1053.           end;
  1054.     reply:record
  1055.           len:word;
  1056.           end;
  1057. Begin
  1058. WITH req
  1059. do begin
  1060.    len:=SizeOf(req)-2;
  1061.    subFunc:=$
  1062.  
  1063.    end;
  1064. Reply.len:=$FF;
  1065. With regs
  1066. do begin
  1067.    AX:=$E300;
  1068.    Ds:=seg(Req);
  1069.    si:=ofs(Req);
  1070.    Es:=seg(Reply);
  1071.    di:=ofs(Reply);
  1072.    MsDos(regs);
  1073.    result:=AL;
  1074.    end;
  1075. With reply
  1076. do begin
  1077.  
  1078.    end;
  1079. template:=(result=0)
  1080. end; }
  1081.  
  1082.  
  1083. {EF03 [2.0/2.1/3.x] secondary Function }
  1084. Function IsConnectionIDinUse( connID: byte ):boolean;
  1085. Type ptarr=^arr;
  1086.      arr=array[0..8*32] of byte;
  1087. Var regs:registers;
  1088. begin
  1089. If ((connID<1) or (ConnID>8))
  1090.  then IsConnectionIDInUse:=TRUE
  1091.  else begin
  1092.       regs.ax:=$EF03;
  1093.       MsDos(regs);
  1094.       IsConnectionIDinUse:=(ptarr(Ptr(regs.es,regs.si))^[(connID-1)*32] = $FF)
  1095.       end;
  1096. end;
  1097.  
  1098.  
  1099.  
  1100. Function GetUserAtConnection( ConnectionNbr:byte; var username: string):boolean;
  1101. {This function provides a shorter method of obtaining just the USERID.}
  1102. var id:LongInt;
  1103.     typ:word;
  1104.     time:NovTimeRec;
  1105. begin
  1106.  getUserAtConnection:=GetConnectionInformation(ConnectionNbr,username,typ,id,time);
  1107. end;
  1108.  
  1109.  
  1110. Function GetEffectiveConnectionID(Var connId:byte):boolean;
  1111. begin
  1112. if NOT (GetPreferredConnectionID(connId) and (connId<>0))
  1113.  then if NOT (GetDefaultConnectionID(ConnId) and (connId<>0))
  1114.        then GetPrimaryConnectionId(ConnId);
  1115. GetEffectiveConnectionID:=(result=$00);
  1116. end;
  1117.  
  1118.  
  1119. Function GetObjectLoginControl(ObjName:string; ObjType:word;
  1120.                                VAR LoginControlInfo:TloginControl):boolean;
  1121. { Caller must have access to the bindery property LOGIN_CONTROL.
  1122.   Default: you need to be supervisor-equivalent or the object the property
  1123.            is associated with. (reading your 'own' information)
  1124.  
  1125.   PasswordcontrolFlag:
  1126.   00 User is allowed to change PW.
  1127.   01 User is NOT allowed to change PW.
  1128.   02 User is allowed to change PW, but the new password must be unique.
  1129.   03 User is NOT allowed to change PW, and a new password, to be changed
  1130.      by the supervisor, must be unique.
  1131. }
  1132. Var LCpropVal:PropertyType;
  1133.     lc:record
  1134.        _AccExpDate          :array[1..3] of byte; {yy mm dd}
  1135.        _AccDisabled         :boolean;
  1136.        _PWexpDate           :array[1..3] of byte; {yy mm dd}
  1137.        _GraceLoginsRemaining:byte;
  1138.        _DaysBetwPWchanges   :word;
  1139.        _MaxGraceLogins      :byte;
  1140.        _minPWlen            :byte;
  1141.        _unknown1            :byte;
  1142.        _MaxConcConn         :byte;
  1143.        _loginTimes          :array[1..42] of byte;
  1144.        _LastLoginTime       :array[1..6] of byte; {yy mm dd hh mm ss}
  1145.        _PWcontrol           :byte;
  1146.        _unknown2            :array[1..6] of byte; {time of last intrusion??}
  1147.        _badLoginCount       :byte;
  1148.        _AccountResetTime    :LongInt; { minutes since 1/1/1985 }
  1149.        _lastIntruderAdress  :TinterNetworkAdress;
  1150.        end        ABSOLUTE LCpropVal;
  1151.     moreSegments:boolean;
  1152.     propFlags:byte;
  1153.  
  1154. begin
  1155. IF nwBindry.ReadPropertyValue(ObjName,ObjType,'LOGIN_CONTROL',1,
  1156.                               LCpropval,moreSegments,propFlags)
  1157.  then begin
  1158.       FillChar(LoginControlInfo,SizeOf(LoginControlInfo),#0);
  1159.       With LoginControlInfo
  1160.        do begin
  1161.           AccountDisabled           :=lc._AccDisabled;
  1162.           move(lc._AccExpDate[1],AccountExpirationDate.year,3);
  1163.           move(lc._PWexpDate[1],PasswordExpirationDate.year,3);
  1164.           MinimumPasswordLength     :=lc._minPWlen;
  1165.           PasswordControlFlag       :=lc._PWcontrol;
  1166.           DaysBetweenPasswordChanges:=swap(lc._DaysBetwPWchanges);
  1167.           Move(lc._lastLoginTime[1],LastLoginTime.year,6);
  1168.           GraceLoginsRemaining      :=lc._GraceLoginsRemaining;
  1169.           MaxGraceLoginsAllowed     :=lc._maxGraceLogins;
  1170.           BadLoginCount             :=lc._badLoginCount;
  1171.           {AccountResetTime         := .. }
  1172.           LastIntruderAdress        :=lc._LastIntruderAdress;
  1173.           LastIntruderAdress.socket :=swap(LastIntruderAdress.socket); {force lo-hi}
  1174.           MaxConcurrentConnections  :=lc._MaxConcConn;
  1175.           Move(lc._LoginTimes[1],LoginTimes[1],42);
  1176.  
  1177.           unknown1:=lc._unknown1;
  1178.           move(lc._unknown2[1],unknown2.year,6);
  1179.           end;
  1180.       end
  1181.  else result:=nwBindry.result;
  1182. end;
  1183.  
  1184.  
  1185. end. { end of unit nwConn }
  1186.  
  1187.