Conocer los puestos disponibles en nuestra red (sólo Windows NT/2000/XP)

Para obtener la lista de PC conectados a nuestra red podemos emplear el método descrito en otra idea de esta sección o bien, utilizar la función NetServerEnum, disponible para Windows NT/2000/XP.

Delphi no incorpora la definición de esta función, por lo que tendremos que hacerlo nosotros. También es posible obtener de la sede del Proyecto Jedi (vea en la sección de enlaces) la traducción a Delphi del API LanManager, con lo que nos ahorramos el trabajo y tendremos todas las funciones, estructuras y constantes definidas.

function NetServerEnum(servername: LPWSTR;
                       level: DWORD;
                       bufptr: Pointer;
                       prefmaxlen: DWORD;
                       entriesread: LPDWORD;
                       totalentries: LPDWORD;
                       servertype: DWORD;
                       domain: LPWSTR;
                       resume_handle: LPDWORD): DWORD; stdcall;
                       external 'NetApi32.dll' name 'NetServerEnum';


Tras la llamada a NetServerEnum es necesario liberar el espacio de memoria utilizado mendiante la función NetApiBufferFree. Tampoco está definida en Delphi, así que…

function NetApiBufferFree(Buffer: Pointer): DWORD; stdcall;
                       external 'NetApi32.dll' name 'NetApiBufferFree';


De entre las estructuras de datos que pueden ser utilizadas con esta función vamos a escoger la SERVER_INFO_100, suficiente para nuestro propósito:

type
  TSERVER_INFO_100 = packed record
    sv100_platform_id: DWORD; // Identificador de plataforma
    sv100_name: LPWSTR;       // Cadena Unicode conteniendo el nombre del puesto
  end;
  PSERVER_INFO_100 = ^TSERVER_INFO_100;

Otras constantes que nos serán de utilidad son:

const
  MAX_PREFERRED_LENGTH = (DWORD(-1));
  SV_TYPE_ALL	= $FFFFFFFF;
  ERROR_MORE_DATA = 234;
  ERR_SUCCESS = 0;


Con todo esto, ya podemos escribir nuestro código, asociado al evento OnClick de un botón (Button1) y almacenar los nombres de los puestos de trabajo devueltos por la función en un ListBox (LisBox1).

procedure TForm1.Button1Click(Sender: TObject);
var
  res: DWORD;
  leidos, total, seguir: DWORD;
  info, tInfo: PSERVER_INFO_100;
  f: Integer;
begin
  ListBox1.Clear;
  seguir := 0;
  repeat
    res := NetServerEnum(nil, 100, @info, MAX_PREFERRED_LENGTH, 
                         @leidos, @total, SV_TYPE_ALL, nil, @seguir);
    tInfo := info;
    if ((res = ERROR_MORE_DATA) or (res = ERR_SUCCESS)) and (leidos > 0) then
      for f := 0 to leidos -1 do
      begin
        ListBox1.Items.Add(tInfo^.sv100_name);
        inc(tInfo);
      end;
    NetApiBufferFree(info);
  until (res <> ERROR_MORE_DATA);
end;