faqts : Computers : Programming : Languages : Delphi

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

7 of 12 people (58%) answered Yes
Recently 7 of 10 people (70%) answered Yes

Entry

Delphi: User: Name: How possibly find out more about all user names? [NetGroupGetUser/UserProfile]

Feb 2nd, 2004 13:54
Knud van Eeden,


----------------------------------------------------------------------
--- Knud van Eeden --- 15 October 2003 - 11:44 pm - 01:34 am ---------

Delphi: User: Name: How possibly find out more about all user names? 
[NetGroupGetUser/UserProfile]

Note:

I did not really find relevant Delphi procedures or functions
to get all user names.

As a possible Windows API

 NetUserEnum

(located as a function in the netapi32.dll, so you basically call this 
function
 in your Delphi program)

might be the candidate.

---
---

[Internet: source: http://www.google.com search for 'get all user 
names Windows API': http://www.mvps.org/access/api/api0058.htm]

API: Enumerating user accounts in a NT Domain

To get a list of all users in a Windows NT/2000 domain, we can use the 
NetUserEnum API function.

---

For an example of 'NetUserEnum' see e.g.:

http://www.nldelphi.com/forum/showthread.php?s=&threadid=6308

---

to download the source code for this example see:

http://www.nldelphi.com/forum/attachment.php?
s=3ad2a3c29f32eefb136d2d2eb3e3dab3&postid=44914

---
---

[Internet: source: http://www.google.com search for 'retrieve all user 
names windows nt': http://www.delphi32.com/vcl/2249/]

Retrieves all the network user names from the given domain. If the 
user do not specify the domain name, it will take from the default 
domain (i.e. the domain to which the machine is connected)

Retrieves all Server(Domain) names on the Network

Freeware,Download with source.

---
---

Check further e.g. the procedures in the dll:

 netapi32.dll

---
---

Another suggestion currently is to possibly read all the 
subdirectories of
the 'c:\documents and settings' directory (e.g. use DOS environment
variables, or Windows API for User Profiles)

---
---

Overview:

Method: use Microsoft Windows Registry

Method: use Microsoft Windows APIs: User profiles

Method: use Microsoft Windows APIs: NetGroup

Method: Read all the subdirectories of the 'c:\documents and settings' 
directory (e.g. use DOS environment variables)


---
---

Method: use Microsoft Windows Registry


in e.g. the location:


HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\Current 
version\Winlogon

you find some more information about the current usernames.

I did not find some information about a list of current usernames.

---
---

Method: use Microsoft Windows APIs: User profiles

---

[Internet: source: http://msdn.microsoft.com/library/default.asp?
url=/library/en-us/policy/policy/user_profiles_functions.asp]

The following functions are used with user profiles.

Function Description

CreateEnvironmentBlock
Retrieves the environment variables for the specified user.

DeleteProfile
Deletes the user profile and all user-related settings from the 
specified computer.

DestroyEnvironmentBlock
Frees environment variables created by the CreateEnvironmentBlock 
function.

ExpandEnvironmentStringsForUser
Expands the source string by using the environment block established 
for the specified user.

GetAllUsersProfileDirectory
Retrieves the path to the root of the All Users profile.

GetDefaultUserProfileDirectory
Retrieves the path to the root of the Default User profile.

GetProfilesDirectory
Retrieves the path to the root directory where all user profiles are 
stored.

GetProfileType
Retrieves the type of profile loaded for the current user.

GetUserProfileDirectory
Retrieves the path to the root directory of the specified user's 
profile.

LoadUserProfile
Loads the specified user's profile.

UnloadUserProfile
Unloads a user's profile that was loaded by the LoadUserProfile 
function.

---

Internet: see also:

How to call Windows API 'GetDefaultUserProfileDirectory' from Delphi?
http://groups.google.com/groups?
q=GetAllUsersProfileDirectory+Delphi&hl=en&lr=&ie=UTF-
8&selm=VA.00000c45.00e31a3f%40gbhstorewkss490&rnum=1

---
---

Method: use Microsoft Windows APIs: NetGroup

[Internet: see also: http://msdn.microsoft.com/library/default.asp?
url=/library/en-us/netmgmt/netmgmt/NetGroupGetUsers.asp]

[Internet: see also: http://www.eksperten.dk/spm/17727]

[Internet: see also: http://www.experts-
exchange.com/Programming/Programming_Languages/Cplusplus/Q_10123245.htm
l]

---

I tried this in Delphi, compiles OK, but currently you will need to 
read and handle the correct parameter information further yourself.

[Internet: source: http://www.google.com search for 'How to get "all 
usernames" windows Delphi': http://www.experts-
exchange.com/Programming/Programming_Languages/Delphi/Q_20544360.html]

1. Open a new application

2. Put a button on the form

3. Put a listbox on the form

4. Put in the following code:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, 
Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
procedure NetAPIBufferFree(Buff: Pointer);
procedure NetGroupGetUsers(Server, GroupName: string;Container: 
TStrings;var buff: Pointer);
procedure NetLocalGroupGetMembers(Server, GroupName: string;Container: 
TStrings;var buff: Pointer);
function Valid:Boolean;
procedure Load;
procedure UnLoad;
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  LIB_NAME = 'NetAPI32.DLL';
  NET_GROUP_GET_USERS_LOCAL  = 'NetLocalGroupGetMembers';
  NET_GROUP_GET_USERS = 'NetGroupGetUsers';
  BUFF_CLEAR = 'NetApiBufferFree';
  MAX_PREFERRED_LENGTH = Cardinal(-1);
  NERR_SUCCESS = 0;
  LEVEL_DISPLAY_USER = 1;
  LEVEL_DISPLAY_MACHINE = 2;
  LEVEL_DISPLAY_GROUP = 3;

type

  PGROUP_USERS_INFO_0 = ^GROUP_USERS_INFO_0;
  GROUP_USERS_INFO_0 = record
    grui0_name: LPWSTR;
  end;

  PLOCALGROUP_MEMBERS_INFO_0 = ^LOCALGROUP_MEMBERS_INFO_0;
  LOCALGROUP_MEMBERS_INFO_0 = record
    lgrmi0_sid: PSID;
  end;

  PLOCALGROUP_MEMBERS_INFO_1 = ^LOCALGROUP_MEMBERS_INFO_1;
  LOCALGROUP_MEMBERS_INFO_1 = record
    lgrmi1_sid: PSID;
    lgrmi1_sidusage: SID_NAME_USE;
    lgrmi1_name: LPWSTR;
  end;

  PLOCALGROUP_MEMBERS_INFO_2 = ^LOCALGROUP_MEMBERS_INFO_2;
  LOCALGROUP_MEMBERS_INFO_2 = record
    lgrmi2_sid: PSID;
    lgrmi2_sidusage: SID_NAME_USE;
    lgrmi2_domainandname: LPWSTR;
  end;

  PLOCALGROUP_MEMBERS_INFO_3 = ^LOCALGROUP_MEMBERS_INFO_3;
  LOCALGROUP_MEMBERS_INFO_3 = record
    lgrmi3_domainandname: LPWSTR;
  end;

TNetAPIBufferFree = function(Buff: Pointer):Integer;stdcall;

TNetGroupGetUsers = function(ServerName, GroupName: LPCWSTR;Level: 
DWORD;bufptr: Pointer;prefmaxlen: DWORD;var entriesread,totalentries: 
LongWord;var ResumeHandle: LongWord):Integer;stdcall;

TNetLocalGroupGetMembers = function(ServerName,LocalGroupName: 
LPCWSTR;level: DWORD;bufptr: Pointer;prefmaxlen: DWORD;var 
entriesread, totalentries: LongWord;var ResumeHandle: 
LongWord):Integer;stdcall;

var
     lHandle: THandle;
     buffclear: TNetAPIBufferFree;
     getgroupusers: TNetGroupGetUsers;
     getlocalgroupusers: TNetLocalGroupGetMembers;

procedure TForm1.NetAPIBufferFree(Buff: Pointer);
begin
  if Valid then
    buffclear(Buff);
end;

procedure TForm1.NetLocalGroupGetMembers(Server, GroupName: 
string;Container: TStrings;var buff: Pointer);
var lpServer, lpGroupName: LPCWSTR;
    ret, cnt: Integer;
    totentr, entread: DWORD;
    p1: PLOCALGROUP_MEMBERS_INFO_3;
    resH: LongWord;
begin
    if Valid then
    begin
      resH:=0;
      GetMem(lpServer,Length(Server)*2+1);
      GetMem(lpGroupName,Length(GroupName)*2+1);
      try
        stringtowidechar(Server,lpServer,Length(Server)*2+1);
        stringtowidechar(GroupName,lpGroupName,Length(GroupName)*2+1);
        repeat
          ret:=getlocalgroupusers
(lpServer,lpGroupName,3,@buff,MAX_PREFERRED_LENGTH,entread,totentr,resH
);
          if (ret = NERR_Success) or (ret = ERROR_MORE_DATA) then
            begin
              p1:=PLOCALGROUP_MEMBERS_INFO_3(buff);
              for cnt:=0 to entread - 1 do
                begin
                  Container.Add('Name: '+p1^.lgrmi3_domainandname);
                  Inc(p1);
                end;
            end
          else
            // CheckReturn(ret);
        until ret <> ERROR_MORE_DATA;
      finally
        FreeMem(lpserver);
      end;
    end
  else
    raise Exception.Create('Unable to load '+LIB_NAME+' or 
function "'+NET_GROUP_GET_USERS_LOCAL+'" not supported');
end;

procedure TForm1.NetGroupGetUsers(Server, GroupName: string;Container: 
TStrings;var buff: Pointer);
var lpServer, lpGroupName: LPCWSTR;
    ret, cnt: Integer;
    totentr, entread: DWORD;
    p1: PGROUP_USERS_INFO_0;
    resH: LongWord;
begin
    if Valid then
    begin
      resH:=0;
      GetMem(lpServer,Length(Server)*2+1);
      GetMem(lpGroupName,Length(GroupName)*2+1);
      try
        stringtowidechar(Server,lpServer,Length(Server)*2+1);
        stringtowidechar(GroupName,lpGroupName,Length(GroupName)*2+1);
        repeat
          ret:=getgroupusers
(lpServer,lpGroupName,0,@buff,MAX_PREFERRED_LENGTH,entread,totentr,resH
);
          if (ret = NERR_Success) or (ret = ERROR_MORE_DATA) then
            begin
              p1:=PGROUP_USERS_INFO_0(buff);
              for cnt:=0 to entread - 1 do
                begin
                  Container.Add('Name: '+p1^.grui0_name);
                  Inc(p1);
                end;
            end
          else
            // CheckReturn(ret);
        until ret <> ERROR_MORE_DATA;
      finally
        FreeMem(lpserver);
      end;
    end
  else
    raise Exception.Create('Unable to load '+LIB_NAME+' or 
function "'+NET_GROUP_GET_USERS+'" not supported');
end;

function TForm1.Valid:Boolean;
begin
   result:=(@buffclear <> nil) and (@getgroupusers <> nil) and 
(@getlocalgroupusers <> nil);
end;

procedure TForm1.Load;
begin
   lHandle:=LoadLIbrary(LIB_NAME);
   if lHandle <> 0 then
     begin
       @buffclear:=GetProcAddress(lHandle,BUFF_CLEAR);
       @getgroupusers:=GetProcAddress(lHandle,NET_GROUP_GET_USERS);
       @getlocalgroupusers:=GetProcAddress
(lHandle,NET_GROUP_GET_USERS_LOCAL);
     end;
end;

procedure TForm1.UnLoad;
begin
  if lHandle <> 0 then
    FreeLibrary(lHandle);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 Load;
 NetGroupGetUsers( '', '', ListBox1.Items, @getgroupusers ); // you 
will have yourself further to experiment with this parameters!!!
end;

end.

---
---

Here an overview of the parameters for NetGroupGetUsers:

[Internet: source: http://www.google.com search 
for 'NetGroupGetUsers': 
http://leb.net/wine/WinDoc/msdn/sdk/platforms/doc/sdk/win32/func/src/f6
0_10.htm]

Parameters
servername
Pointer to a Unicode string containing the name of the remote server 
on which the function is to execute. A NULL pointer or string 
specifies the local computer.

groupname
Pointer to a Unicode string containing the name of the global group 
whose members are to be listed.

level
Specifies one of the following values to return the level of 
information pointed to in the bufptr parameter. Value
 Meaning

0
 Return the group name. The returned buffer points to an array of 
GROUP_USERS_INFO_0 structures.

1
 Return the group attributes. The returned buffer points to an array 
of GROUP_USERS_INFO_1 structures.


bufptr
On return a pointer to the return information structure is returned in 
the address pointed to by bufptr. The returned buffer should be 
deallocated using NetApiBufferFree.

prefmaxlen
Preferred maximum length, in 8-bit bytes of returned data.

entriesread
Pointer to a DWORD that contains the actual enumerated element count.

totalentries
Pointer to a DWORD that contains the total number of entries that 
could have been enumerated from the current resume position.

resumeHandle
Pointer to a DWORD that contains resumeHandle, which is used to 
continue an existing user group search. The handle should be zero on 
the first call and left unchanged for subsequent calls. If 
resumeHandle is NULL, then no resume handle is stored.

---
---

Method: use DOS environment variables

Steps: Overview:

 1. -Goto DOS command line

 2. -Type

      set

     then search e.g. for the word 'doc'

 3. -You will see (in Microsoft Windows XP) then the environment 
variables:

      ALLUSERSPROFILE=C:\Documents and Settings\All Users

      APPDATA=C:\Documents and Settings\Administrator\Application Data

      HOMEPATH=\Documents and Settings\Administrator

      TEMP=C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp

      TMP=C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp

      USERPROFILE=C:\Documents and Settings\Administrator

 4. -You can then use this environment variables (by reading them in
     Delphi, using e.g. 'ExpandEnvironmentStrings') to find out more 
about the current users, by checking the
     subdirectories in e.g. 'c:\documents and settings'

Internet: see also:
http://groups.google.com/groups?q=%25PROGRAMFILES%
25+ExpandEnvironmentStrings+Delphi+Borland&hl=en&lr=&ie=UTF-8&oe=UTF-
8&selm=3e722d7f%40newsgroups.borland.com&rnum=1

 5. -To see all users on this computer, type then e.g.:

      dir "c:\documents and settings"

     and you see from the existing subdirectories which are all the 
current users of this computer:

        Volume in drive C has no label.
        Volume Serial Number is 6CBC-C01A

        Directory of c:\documents and settings

       09/26/2003  21:33 PM    <DIR>          .
       09/26/2003  21:33 PM    <DIR>          ..
       10/15/2003  19:12 PM    <DIR>          Administrator
       04/23/2003  15:07 PM    <DIR>          All Users
       09/26/2003  21:33 PM    <DIR>          Johnny Doe
       09/26/2003  21:33 PM    <DIR>          Vanessa Doll

 6. -So in Delphi you could get all the user names by reading the names
     all this subdirectories of 'c:\documents and settings'

---
---

[Internet: source: http://www.google.com search for 'NetAPI32.DLL 
Delphi user': http://www.vclcomponents.com/x_authors.asp?
ID_AUTHOR=7381]

 ntuser.zip  Version: n/a  D3|D4
  45 kB    Hits: 155 Source: NO  Not reviewed
TNTUserAdmin is a non-visual component which allows you to 
administrate (view, edit, add and delete) user s account on a Windows 
NT domain controller. It uses exported functions in NT s DLL 
NETAPI32.DLL.

---
---

[Internet: source: http://www.google.com search for ''How to get "all 
usernames" windows Delphi'': 
http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=19336]

Retreive all usernames from the WinNT server

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