Delphi Tutorial - Getting a User List on NT

'

Using NetGetDCName and NetUserEnum found in netapi32.dll

Windows exposes LanMan 32-bit Application Programming Interfaces (APIs) to provide network services. These APIs are called from 32-bit programs  and are used to control both the local remote Windows  machines that you have permission to access.

The following code sample demonstrates how to retrieve information about the user accounts on a server with a call to the NetUserEnum . 

User account names are limited to 20 characters and group names are limited to 256 characters. In addition, account names cannot be terminated by a period and they cannot include commas or any of the following printable characters: ", /, \, [, ], :, |, <, >, +, =, ;, ?, *. Names also cannot include nonprintable characters in the ranges 1-7, 10-17, 20-27, and 30-37.

First, we will need some API functions:

Const 
   NERR_Success = 0; 

function NetApiBufferAllocate(ByteCount: DWORD; var Buffer: Pointer): DWORD; 
                                           stdcall; external 'netapi32.dll'; 
function NetGetDCName(servername: LPCWSTR; domainname: LPCWSTR; 
  bufptr: Pointer): DWORD; stdcall; external 'netapi32.dll'; 
function NetApiBufferFree (Buffer: Pointer): DWORD ; stdcall; 
                                     external 'netapi32.dll'; 
Function NetWkstaGetInfo 
        (ServerName : LPWSTR; 
         Level      : DWORD; 
         BufPtr     : Pointer) : Longint; Stdcall; 
                external 'netapi32.dll' Name 'NetWkstaGetInfo'; 

function NetUserEnum(servername: LPCWSTR; level: DWORD; filter: DWORD; 
  var bufptr: Pointer; prefmaxlen: DWORD; var entriesread: DWORD; 
  var totalentries: DWORD; resume_handle: PDWORD): DWORD; stdcall; 
                                          external 'netapi32.dll'; 

type 
  WKSTA_INFO_100   = Record 
      wki100_platform_id  : DWORD; 
      wki100_computername : LPWSTR; 
      wki100_langroup     : LPWSTR; 
      wki100_ver_major    : DWORD; 
      wki100_ver_minor    : DWORD; 
                            End; 

   LPWKSTA_INFO_100 = ^WKSTA_INFO_100; 

  _USER_INFO_0  = record 
    usri0_name: LPWSTR; 
  end; 
  TUserInfo0 = _USER_INFO_0; 

You must be a member of the Administrators local group to successfully execute NetWkstaSetInfo on a remote server or on a computer that has local security enabled.

function GetNetParam(AParam : integer) : string; 
Var 
  PBuf  : LPWKSTA_INFO_100; 
  Res   : LongInt; 
begin 
  result := ''; 
  Res := NetWkstaGetInfo (Nil, 100, @PBuf); 
  If Res = NERR_Success Then 
    begin 
      case AParam of 
       0:   Result := string(PBuf^.wki100_computername); 
       1:   Result := string(PBuf^.wki100_langroup); 
      end; 
    end; 
end;

Following function returns the name of the local computer:

function GetComputerName : string; 
begin 
  Result := GetNetParam(0); 
end; 

Following function returns the name of the domain to which the computer belongs:

function GetDomainName : string; 
begin 
  Result := GetNetParam(1); 
end; 

The GetDomainControllerName function returns the name of the primary domain controller (PDC). It does not return the name of the backup domain controller (BDC) for the specified domain.

function GetDomainControllerName(const ADomainName : string) : string; 
var 
  wDomainName : WideString; 
  Controller : PWideChar; 
begin 
  wDomainName := AdomainName; 
  NetGetDCName (Nil, PWideChar (wDomainName), @Controller); 
  Result := WideCharToString(controller); 
  NetAPIBufferFree (Controller); 
end; 
 

procedure GetUsers(Users : TStringList; AServer : string); 
type 
  TUserInfoArr = array[0..(MaxInt - 4) div SizeOf(TUserInfo0)] of TUserInfo0;
var 
  UserInfo: Pointer; 
  EntriesRead, TotalEntries, ResumeHandle: DWORD; 
  Res: DWORD; 
  i: Integer; 
  FServer : WideString; 
begin 
  FServer :=  AServer; 
  ResumeHandle := 0; 
  repeat 
    Res := NetUserEnum(PWideChar(FServer), 0, 0, UserInfo, 
                       64 * SizeOf(TUserInfo0),
                       EntriesRead, TotalEntries, @ResumeHandle); 
    if (Res = NERR_SUCCESS) or (Res = ERROR_MORE_DATA) then 
    begin 
      for i := 0 to EntriesRead - 1 do 
        Users.Add(TUserInfoArr(UserInfo^)[i].usri0_name); 
      NetApiBufferFree(UserInfo); 
    end; 
  until Res <> ERROR_MORE_DATA; 
end; 

To get a list of the users on local computer you can use the result of the function GetComputerName as a second parameter of the GetUsers function.

To get a list of the users from PDC you can use GetDomainController function to get PDC name.

If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to achieve the same functionality you can achieve by calling the network management user functions.

This tutorial was kindly provided by serge perevoznyk


Google
Web www.Delphi-Central.com
Delphi Central - Delphi Programming Tutorials, Hints and Tips