We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

Login name on NT4

rene_moeller
rene_moeller asked
on
Medium Priority
584 Views
Last Modified: 2010-04-06
How do i get the login name from another NT4 workstation in the network?
Comment
Watch Question

Commented:
Do you mean you supply the computer name and get the currently logged on console user ?

Author

Commented:
Yes, a more exactly way to put it. And a little piece of code would be nice.
Hi

  If your application uses the BDE, you can use the following code to get the user logged on:

function GetCurrUser : String;
var
  pcNetUser : PChar;
begin
  pcNetUser := StrAlloc (256);  

  if DbiGetNetUserName (pcNetUser) = 0 then
    Result := StrPas (pcNetUser)
  else
    Result := '';  

  StrDispose (pcNetUser);
end;

I hope this helps with the username.

Edo
Hi
  I just found this after some digging.

>>Untested.

procedure GetComputerName
var
  i : integer;
  ComputerName : string;
begin
  SetLength(ComputerName,NSize);
  if GetComputerName(PChar(ComputerName), NSize) then
    StatusBar.Panels[1].Text:= 'PC: '+ ComputerName;
end;

HTH

Edo

Author

Commented:
Thx EDO, but I don't use BDE in the app. I'll keep the example in mind to another time.

Commented:
mmh, I am fighting around with some netapi32.dll calls right now, always get GPFs... I'll keep digging.

Slash/d003303

Author

Commented:
Hi d003303,
I knew this was a "tuffy". Still getting GPF's?

Commented:
Unlock this solution with a free trial preview.
(No credit card required)
Get Preview

Author

Commented:
Thanks d003303,

I'll test it in the week-end. It looks very promising.

Commented:
oops, I forgot to implement the new exception handler.
The lines
type

  ENetAPIException = class(Exception)
    NetAPIErrorCode : LongInt;
  end;

  PWKSTA_USER_INFO_0 = ^TWKSTA_USER_INFO_0;
should read
type

  ENetAPIException = class(Exception)
    NetAPIErrorCode : LongInt;
    constructor Create(AMsg : string; ErrCode : LongInt);
  end;

constructor ENetAPIException.Create(AMsg : string; ErrCode : LongInt);
begin
  inherited Create(AMsg);
  NetAPIErrorCode := ErrCode;
end;

type

  PWKSTA_USER_INFO_0 = ^TWKSTA_USER_INFO_0;
and the lines
          if (FResult = ERROR_MORE_DATA) and (UsrTotal <> 0)
           then PrefMaxLen := PrefMaxLen * 2
           else raise Exception.Create('NetWkstaUserEnum ' + IntToStr(FResult));
should read
          if (FResult = ERROR_MORE_DATA) and (UsrTotal <> 0)
           then PrefMaxLen := PrefMaxLen * 2
           else raise ENetAPIException.Create('Error calling NetWkstaUserEnum', FResult);

Happy testing,
Slash/d003303

Author

Commented:
Thanks d003303,

You are nothing less than brilliant. It works and it was exacltly what I was looking for. Thanks again.

Commented:
Thx, no prob.

Commented:
Yo,
another method to get the logged on user(s), but only if they are logged on interactively. This returns one entry for ordinary NT WS/Server, and a list of all users connected via terminals/console on e.g. Citrix WinStation or Hydra (tested).

procedure GetUsersFromRemoteReg(WksName : string; HiveList : TStrings);
var Registry : TRegistry;
    Index    : Integer;
begin
  Registry := TRegistry.Create;
  try
    Registry.RootKey := HKEY_USERS;
    if not Registry.RegistryConnect(WksName)
     then Exit;
    Registry.OpenKey('', false);
    if Registry.HasSubkeys then
     begin
       Registry.GetKeyNames(HiveList);
       for Index := 0 to HiveList.Count - 1
        do if UpperCase(HiveList[Index]) = '.DEFAULT' then
         begin
           HiveList.Delete(Index);
           Break;
         end;
      end;
    Registry.CloseKey;
  finally
    Registry.Free;
  end;
end;

procedure TranslateSIDToAccountNames(WksName : string; HiveList : TStrings);
var Registry : TRegistry;
    lUsrName,
    lDomName,
    lSID,
    peUse,
    Index    : Integer;
    UsrName,
    DomName,
    SID      : PChar;
begin
  Registry := TRegistry.Create;
  try
    Registry.RootKey := HKEY_LOCAL_MACHINE;
    if not Registry.RegistryConnect(WksName)
     then Exit;
    for Index := 0 to HiveList.Count - 1 do
     if Registry.OpenKey('SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\' + HiveList[Index], false) then
      begin
        lSID := Registry.GetDataSize('Sid');
        GetMem(SID, lSID);
        try
          Registry.ReadBinaryData('Sid', SID[0], lSID);
          if IsValidSid(SID) then
           begin
             lUsrName := 0;
             lDomName := 0;
             LookupAccountSid(PChar(WksName), SID, UsrName, lUsrName, DomName, lDomName, peUse);
             GetMem(UsrName, lUsrName);
             GetMem(DomName, lDomName);
             try
               if not LookupAccountSid(PChar(WksName), SID, UsrName, lUsrName, DomName, lDomName, peUse)
                then raise Exception.Create('LookupAccountSid failed');
               HiveList[Index] := string(DomName) + '\' + string(UsrName);
             finally
               FreeMem(DomName, lDomName);
               FreeMem(UsrName, lUsrName);
             end;
           end;
        finally
          Registry.CloseKey;
          FreeMem(SID, lSID);
        end;
      end;
  finally
    Registry.Free;
  end;
end;

Call these functions like the above example,

    GetUsersFromRemoteReg(Edit1.Text, Listbox1.Items);
    TranslateSIDToAccountNames(Edit1.Text, Listbox1.Items);

and have fun.
Slash/d003303
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a free trial preview!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.