From: "Sajan Thomas" <THOMAS@warp.msoe.edu>
Subject: [delphi] Network User Name, etc.....
Date:          Tue, 1 Aug 1995 20:04:45 CST6

Hi everybody,
   I hope somebody finds the following code useful.  
This code has been adapted from ALLSWAG.  It returns the Network 
station number, user name and full name.  I have tested it with 
Novell Netware 3.12 and WFW.  

    At least I hope this will save some of you some time.  It took me 
some time to figure out exactly how to get it done.  (Now it appears 
clearer *grins*)

Even if you don't understand the details, you can still use the 
functions.  For the sake of those like me, who are new to the 
language:  You can copy the code in between the dotted lines and put 
it in a file and use it as a unit.

----------Code begins------------------------
unit General;

interface
function StationNumber:byte;
Function GetNetUserName : String;
Function GetNetFullName(User_Name : String) : String;

implementation
function StationNumber:byte;  { MY logical Station(connection)-Number }
var
 RetVal : Byte;
begin
 asm
   MOV AH, $DC;
   INT 21H
   MOV RetVal, AL;
 end;
 Result := Retval;
end;


Function GetNetUserName : String;

var
  Request : record                     { Request buffer for "Get Conn Info" }
    Len  : Word;                       { Buffer length - 2                  }
    Func : Byte;                       { Subfunction number ( = $16 )       }
    Conn : Byte                        { Connection number to be researched }
  end;

  Reply    : record                    { Reply buffer for "Get Conn Info"   }
    Len    : Word;                     { Buffer length - 2                  }
    ID     : Longint;                  { Object ID (hi-lo order)            }
    Obj    : Word;                     { Object type (hi-lo order again)    }
    Name   : array[ 1..48 ] of Byte;   { Object name as ASCII string        }
    Time   : array[ 1.. 7 ] of Byte;   { Y, M, D, Hr, Min, Sec, DOW         }
                                       { Y < 80 is in the next century      }
                                       { DOW = 0 -> 6, Sunday -> Saturday   }
    Filler : Byte                      { Call screws up without this!       }
  end;

  W      : Word;
  RetVal : Byte;

begin
                                       { "Get Connection Information"       }
  with Request do                      { Initialize request buffer:         }
  begin
    Len := 2;                                    { Buffer length,           }
    Func := $16;                                 { API function,            }
    Conn := StationNumber                    { Returned in previous call!         }
  end;

  Reply.Len := SizeOf( Reply ) - 2;    { Initialize reply buffer length     }

  asm
   push ds
   push ss
   push es
    MOV AH, $E3;                         { Connection Services API call       }
    LEA SI, Request               { Location of request buffer         }
    PUSH SS
    POP DS
    LEA DI, Reply                { Location of reply buffer           }
    PUSH SS
    POP ES
    INT 21H
    MOV RetVal, AL
    pop ES
    pop SS
    pop DS
  end;

  if ( RetVal = 0 )                        { Success code returned in AL   }
       and ( Hi( Reply.Obj ) = 1 )          { Obj of 1 is a user,           }
       and ( Lo( Reply.Obj ) = 0 ) then     {   stored Hi-Lo                }
    with Reply do
    begin
      Move( Name, Result[ 1 ], 48 );           { Convert ASCIIZ to string }
      Result[ 0 ] := #48;
      W := 1;
      while ( Result[ W ] <> #0 )
            and ( W < 48 ) do
        Inc( W );
      Result[ 0 ] := Char( W - 1 )
    end
  else
    Result := ''
end;


Function GetNetFullName(User_Name : String) : String;
Type
  RequestBuffer = Record
    RequestBufferLength : Word;
    Code                : Byte;
    ObjectType          : Word;
    ObjectNameLength    : Byte;
    ObjectName          : Array[1..48] of char;
    SegmentNumber       : Byte;
    PropertyNameLength  : Byte;
    PropertyName        : Array[1..15] of char;
  end;

  ReplyBuffer = Record
    ReplyBufferLength : Word;
    PropertyValue     : Array[1..128] of char;
    MoreSegments      : Byte;
    PropertyFlags     : Byte;
  end;

Var
  Request : RequestBuffer;
  Reply   : ReplyBuffer;
  PropertyName : String[15];
  Counter : Byte;
  Temp    : String[128];

begin
  PropertyName := 'IDENTIFICATION';
  Request.RequestBufferLength := SizeOf(Request) - 2;
  Request.Code := $3D;
  Request.SegmentNumber := 1;
  Request.ObjectType := $0100;
  Request.ObjectNameLength := SizeOf(Request.ObjectName);
  FillChar(Request.ObjectName, SizeOf(Request.ObjectName), #0);

  For Counter := 1 to length(User_Name) do
    Request.ObjectName[Counter] := User_Name[Counter];

  Request.PropertyNameLength := SizeOf(Request.PropertyName);
  FillChar(Request.PropertyName, SizeOf(Request.PropertyName), #0);

  For Counter := 1 to Length(PropertyName) do
    Request.PropertyName[Counter] := PropertyName[Counter];
  Reply.ReplyBufferLength := SizeOf(Reply) - 2;

 asm
  PUSH SS
  PUSH DS
  MOV AH, $E3;
  LEA SI, Request
  PUSH SS
  POP DS
  LEA DI,Reply
  PUSH SS
  POP ES
  INT 21H
  POP DS
  POP SS
 end;

  Temp := '';
  Counter := 1;
  While (Reply.PropertyValue[Counter] <> #0) do
  begin
    Temp := Temp + Reply.PropertyValue[Counter];
    inc(Counter);
  end;
  Result := Temp;
end;
end.
-------------Code Ends------------------------

Sajan Thomas
Computer and Communication Services Department
Milwaukee School of Engineering
Milwaukee, WI 53202
Tel. (414)-277-7498
(Internet Address: THOMAS@MSOE.EDU)

-------------------------------------------------------------------------------

From: "Sajan Thomas" <THOMAS@warp.msoe.edu>
Subject: [delphi] Netware Login Time
Date: Wed, 2 Aug 1995 11:07:43 CST6

Hi everybody,
   Here is a function to get the login date and time from Netware.
The function returns the result in TDateTime format, which can be 
formatted with any of the built-in routines.
e.g.
DateString := FormatDateTime('"I  logged in on" dddd, mmmm d, yyyy, ' +
'"at" hh:mm AM/PM', GetLoginTime(stationnumber)); 
 returns the login date and time for the current user. ( It uses the 
StationNumber function that I posted yesterday).
   You can find out the login date and time for any station, provided 
you _know_ the station number.  The results of the function when 
supplied a non-existant station number is unpredictable!!
   Again, this function has been adapted from material found in the 
ALLSWAG.ZIP file.

  Hope this helps someone.

Enjoy,
Sajan.


----code begins--------------------
Function GetLoginTime(LogicalStationNo: Integer):TDateTime;
Var
  I,X            : Integer;
  RequestBuffer  : Record
                     PacketLength : Integer;
                     FunctionVal  : Byte;
                     ConnectionNo : Byte;
                   end;
  ReplyBuffer    : Record
                     ReturnLength : Integer;
                     UniqueID1    : Packed Array [1..2] of Byte;
                     UniqueID2    : Packed Array [1..2] of Byte;
                     ConnType     : Packed Array [1..2] of Byte;
                     ObjectName   : Packed Array [1..48] of Byte;
                     LoginTime    : Packed Array [1..8] of Byte;
                   end;
  Month          : String[3];
  Year,
  Day,
  Hour,
  Minute         : String[2];
  retval : byte;

Begin
  With RequestBuffer Do begin
    PacketLength := 2;
    FunctionVal := 22;  { 22 = Get Station Info }
    ConnectionNo := LogicalStationNo;
  end;
  ReplyBuffer.ReturnLength := 62;
  asm
    push ds
    push ss
    mov ah, $e3;
    lea SI, RequestBuffer
    push ss
    pop ds
    lea di, ReplyBuffer
    push ss
    pop es
    int 21h
    mov retval, al
    pop ss
    pop ds
  end;
  if RetVal = 0 then
   begin
    With ReplyBuffer Do
     begin
       Str(LoginTime[1]:2,Year);
       Str(LoginTime[2], Month);
       Str(LoginTime[3]:2,Day);
       Str(LoginTime[4]:2,Hour);
       Str(LoginTime[5]:2,Minute);
       if Day[1] = ' ' then Day[1] := '0';
       if Hour[1] = ' ' then Hour[1] := '0';
       if Minute[1] = ' ' then Minute[1] := '0';
       Result := StrToDateTime(Month+'/'+Day+'/'+Year+' ' + Hour + ':' + Minute);
    end { With };
   end;
End;
----------code ends-----------------

Sajan Thomas
Computer and Communication Services Department
Milwaukee School of Engineering
Milwaukee, WI 53202
Tel. (414)-277-7498
(Internet Address: THOMAS@MSOE.EDU)

-------------------------------------------------------------------------------

From: "Sajan Thomas" <THOMAS@warp.msoe.edu>
Subject: [delphi] Netware API functions - partial set
Date: Thu, 3 Aug 1995 13:32:12 CST6

Hi all,
  I just took a look at the NIVB.ZIP.  It certainly has all the 
information anybody would want (well, most of it atleast).
I converted a couple of functions into Delphi.  Here is the partial 
list.  As time permits, I'll convert more of the functions.  
   Somebody had wanted to get the Network address, node address etc.  
They are in here.  The only limitation is that NWNETAPI.DLL must be 
present for the function calls to work.
  Hope someone finds this useful.  

---------code begins------------------
unit Netapi;

interface
type
 TFileServerName = array [0..48] of char;
 TNodeAddress = record
    nodeHi : longint;
    nodeLo : Integer;
    end;


Function GetConnectionNumber:Longint;
Function GetConnectionID(fileServerName:TFileServerName; var connectionID:integer):Integer;
Function GetDefaultConnectionID:Integer;
Procedure GetFileServerName(connID:integer; var fileservername:TFileServerName);
Function GetInternetAddress(connectionNumber : longint; var networkNumber: longint;
         var physicalNodeAddress:TNodeAddress; var socketNumber: integer):Integer;
Function IntSwap(unswappedInteger : integer):Integer;
Function LongSwap(unswappedLong : longint):Longint;
Function GetNetworkNumber : String;
Function GetNodeAddress : String;
{Call example: FileServerName(GetDefaultConnectionID) }
Function FileServerName(connID : integer) : String;


implementation
Uses SysUtils;
Function GetInternetAddress; external 'NWNETAPI';
Function GetConnectionNumber; external 'NWNETAPI';
Function GetConnectionID; external 'NWNETAPI';
Function GetDefaultConnectionID; external 'NWNETAPI';
Procedure GetFileServerName; external 'NWNETAPI';
Function IntSwap; external 'NWNETAPI';
Function LongSwap; external 'NWNETAPI';

Function GetNetworkNumber : String;
 var
  networkno : longint;
  nodeaddr : TNodeAddress;
  socketno : integer;
Begin
 GetInternetAddress(GetConnectionNumber,networkno, nodeaddr, socketno);
 Result := IntToHex(LongSwap(networkno), 1);
End;



Function GetNodeAddress : String;
 var
  networkno : longint;
  nodeaddr : TNodeAddress;
  socketno : integer;
Begin
 GetInternetAddress(GetConnectionNumber,networkno, nodeaddr, socketno);
 Result := IntToHex(longswap(nodeaddr.nodehi), 1) +
           IntToHex(lo(nodeaddr.nodelo), 1) +
           IntToHex(hi(nodeaddr.nodelo), 1);
End;

Function FileServerName(connID : integer) : String;
Var
 FSName : TFileServerName;
Begin
 FillChar(FSName, 48, ' ');  {need to initialize it}
 GetFileServerName(connID, FSName);
 Result := StrPas(FSName);
End;

end.
---------- code ends---------------

Enjoy,
Sajan.

Sajan Thomas
Computer and Communication Services Department
Milwaukee School of Engineering
Milwaukee, WI 53202
Tel. (414)-277-7498
(Internet Address: THOMAS@MSOE.EDU)

