The Road to Delphi

Delphi – Free Pascal – Oxygene

Delphi : Enumerating Remote Desktop Servers in a network domain

4 Comments

Using the WinApi WTSEnumerateServers function you can get a list of all Remote Desktop Servers in a network domain.

Check this code. Tested on Delphi 2007, Delphi 2010, Delphi XE – (Windows XP/7/2008 Server)

program GetRemoteDesktops;

{$APPTYPE CONSOLE}

type
PWTS_SERVER_INFO = ^WTS_SERVER_INFO;
_WTS_SERVER_INFO = packed record
pServerName:LPTSTR;
end;
WTS_SERVER_INFO = _WTS_SERVER_INFO;
WTS_SERVER_INFO_Array  = Array [0..0] of WTS_SERVER_INFO;
PWTS_SERVER_INFO_Array =^WTS_SERVER_INFO_Array;

{$IFDEF UNICODE}
function WTSEnumerateServers( pDomainName: LPTSTR; Reserved: DWORD; Version: DWORD; ppServerInfo: PWTS_SERVER_INFO; pCount: PDWORD):BOOLEAN; stdcall; external 'wtsapi32.dll'  name 'WTSEnumerateServersW';
{$ELSE}
function WTSEnumerateServers( pDomainName: LPTSTR; Reserved: DWORD; Version: DWORD; ppServerInfo: PWTS_SERVER_INFO; pCount: PDWORD):BOOLEAN; stdcall; external 'wtsapi32.dll'  name 'WTSEnumerateServersA';
{$ENDIF}
procedure WTSFreeMemory(pMemory:Pointer);stdcall; external 'wtsapi32.dll' name 'WTSFreeMemory';

procedure GetRemoteDesktopsList(const Domain:PChar;const Servers:TStrings);
var
ppServerInfo : PWTS_SERVER_INFO_Array;//PWTS_SERVER_INFO;
pCount       : DWORD;
i            : integer;
begin
  Servers.Clear;
  ppServerInfo:=nil;
  try
    if WTSEnumerateServers(Domain,0,1,PWTS_SERVER_INFO(@ppServerInfo),@pCount) then
      for i := 0 to pCount - 1 do
        Servers.Add(ppServerInfo^[i].pServerName)
    else
    Raise Exception.Create(SysErrorMessage(GetLastError));
  finally
    if ppServerInfo<>nil then
    WTSFreeMemory(ppServerInfo);
  end;
end;

Author: Rodrigo

Just another Delphi guy.

4 thoughts on “Delphi : Enumerating Remote Desktop Servers in a network domain

  1. Jwscl (Jedi Windows Security Library) has a special unit for Terminal Server (JwsclTerminalServer) that amongst others offers Server Enumeration. And since in larger environments or when queried from a slow connection (eg WAN) this can be a lengthy operation it is automatically done in a Thread and signals an event when done.

    • Remko, i really knew about the existence of the JwsclTerminalServer unit in the Jwscl library. whenever I can recommend use this library. in this case, this is just a simple snippet to show a specific functionality.

  2. I think there are problems with this code:
    – the pCount pointer is unitialized
    – You are not free-ing the memory (ppServerInfo) (WtsFreeMemory)
    – If you would free it you would have the problem that you increased the pointer so you cannot pass that inc-ed address to WtsFreeMemory
    – You are not derefencing the pointer (Servers.Add(ppServerInfo^.pServerName);) although this is not a real error

    BTW: Jwscl has a really nice Terminal Server unit (JwsclTerminalServer) that has a nice threaded implementation for Server Enumeration since this can be a lengthy operation in larger environments or when querying through a slow connection.

Leave a comment