'===========================================================================
' Subject: PB RETURN USER NAME ON NETWORK     Date: 09-10-97 (20:05)       
'  Author: Scott Slater                       Code: PB                     
'  Origin: captain@usaor.net                Packet: NETWORK.ABC
'===========================================================================
' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
' Program Title: WHO.BAS
'     Copyright: Donated to PUBLIC DOMAIN By Scott Slater
'        Author: Scott Slater
' Last Modified: 09/10/1997
' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
'   Description: Similar to Novell's WHOAMI command but written in PB!
' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
'         Notes: MUST BE COMPILED WITH PowerBASIC v3.2 or Higher.
' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
'       History: none, but look for a QuickBASIC version also.
' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

$cpu 8086                 ' program works on any CPU

$optimize size            ' make smallest possible executable
$compile exe              ' compile to an EXE

$debug map off            ' turn off map file generation
$debug pbdebug off        ' don't include pbdebug support in our executable

$lib all        off       ' turn off PowerBASIC's internal libraries.
$error all      off       ' turn off all error checking

$com    0                 ' set communications buffer to nothing
$string 16                ' set largest string size at 16k
$stack  2048              ' use a 2k stack
$sound  1                 ' smallest music buffer possible

$dim all                  ' force all variables to be pre-dimensioned before
                          ' they can be used
$dynamic                  ' all arrays will be dynamic by default

$option cntlbreak off     ' don't allow Ctrl-Break to exit program


declare function get_con_num() as dword
declare function get_con_stat(con_num as dword) as string


dim connect as dword                  ' dword to hold connection number
dim work as word                      ' work variable
dim li as string                      ' buffer for login time
dim nm as string                      ' string representation for each unit
dim cs as string                      ' string to hold connection status

connect = get_con_num

if connect then
   print "Logical Connection Number";connect
else
   print "Not connected"
   end
end if

$IF 0

  The function  get_con_stat will return either a nul string if there is no
connection or login, or it will return a 62 byte string that can be broken
down as follows:

   Offset    Size    Description
   00h       DWORD   unique user ID
   04h       WORD    user type
   06h   48  BYTEs   user name
   36h    7  BYTEs   login time
   3Dh       BYTE    reserved

$ENDIF

cs = get_con_stat(connect)

if cs = "" then                       ' see if we have a connection, cs will
   print "Not logged in"              ' be NUL if we don't
else                                  ' otherwise we are connected
   li = mid$(cs,55,7)                 ' fill the login time buffer
   print "UserName    : "; mid$(cs,7,48)   ' show the current username
   print "Login time  : ";
   work = ascii(mid$(li,4,1))         ' get the hour of login
   nm = ltrim$(rtrim$(str$(work)))    ' convert it to a string
   if work < 10 then nm = "0" + nm    ' if single digit add a preceeding 0
   print nm;":";                      ' print the hour
   work = ascii(mid$(li,5,1))         ' get the minute of login
   nm = ltrim$(rtrim$(str$(work)))    ' convert it to a string
   if work < 10 then nm = "0" + nm    ' if single digit add a preceeding 0
   print nm;":";                      ' print minutes
   work = ascii(mid$(li,6,1))         ' get the second of login
   nm = ltrim$(rtrim$(str$(work)))    ' convert it to a string
   if work < 10 then nm = "0" + nm    ' if single digit add a preceeding 0
   print nm                           ' finaly, print the seconds
end if

print                                 ' extra line

end                                   ' see ya!



function get_con_num () public as dword

' NetWare CONNECTION SERVICES - GET CONNECTION NUMBER Function DCh

   dim connection_number as local byte

   !   mov ah, &HDC                        ; function DCh
   !   int &H21                            ; call interrupt 21h
   !   mov connection_number, al           ; al holds the connection number
                                           '   or a 0 if no connection.
   function = connection_number

end function

function get_con_stat(con_num as dword) public as string
   dim len_of_data as word
   dim subfunct as byte

   dim reqt as string * 7
   dim repl as string * 62

   dim d1 as dword ptr
   dim d2 as dword ptr
   dim w1 as word ptr
   dim w2 as word ptr
   dim b1 as byte ptr
   dim b2 as byte ptr                 ' 2's are pointers to string

   dim seg1 as word, seg2 as word, off1 as word, off2 as word, trys as word


   ' Set up Request Buffer

   len_of_data = 5                    ' length of following data
   subfunct = &H1C                    ' subfunction "Get Connection Info"

   w1 = varptr32(len_of_data)         ' pointer to len_of_data
   b1 = varptr32(subfunct)            ' pointer to subfunct
   d1 = varptr32(con_num)             ' pointer to con_num
   b2 = varptr32(reqt)                ' byte pointer to byte 1 of reqt

   w2 = b2                            ' initialize all string pointers to
   d2 = b2                            ' point to the first byte of reqt
   incr b2, 2                         ' Position of byte in string
   incr d2, 3                         ' Position of dword in string

   ' move the data

   @w2 = @w1                          ' move the word data to the string
   @b2 = @b1                          ' move the byte data to the string
   @d2 = @d1                          ' move the dword data to the string


   ' call asm routine to get the information from NetWare Connection Services

   ' NetWare GET CONNECTION INFORMATION Function F2h

   if con_num then

      seg1 = varseg(reqt)             ' segment address of reqt
      off1 = varptr(reqt)             ' offset of reqt
      seg2 = varseg(repl)             ' segment address of repl
      off2 = varptr(repl)             ' offset of repl

   rtry:

      !   push ds                     ; save ds for powerbasic
      !   mov ax, &HF217              ; function F217h
      !   mov cx, 7                   ; length of request packet (reqt)
      !   mov dx, 62                  ; length of reply packet (repl)
      !   mov ds, seg1                ; point ds:si to address of request
      !   mov si, off1                ;    packet
      !   mov es, seg2                ; point es:di to address of reply
      !   mov di, off2                ;    packet
      !   int &H21                    ; call interrupt 21h
      !   pop ds                      ; restore the ds
      !   mov subfunct, al            ; copy the contents of al into subfunct
      !   cmp al, 0                   ; if it returns 0, success
      !   je done                     ; so jump to label "done"
      !   inc trys                    ; otherwise increment our counter by 1
      !   cmp trys, 100               ; have we made 100 trys?
      !   je done                     ; if so jump to label "done"
      !   jmp rtry                    ; otherwise jump to label "rtry"

   done:

      if trys = 100 then
         function = ""
      else
         function = repl
      end if

   else
      function = ""
   end if

end function
