Как получить список компьютеров в локальной сети - by Mark Shevchenko
( выдержки из документа )
Это один из тех вопросов, который иногда пробегает по иерархии RU.DELPHI.*. В этой статье мы рассмотрим, как можно получить список компьютеров в сети. Для начала вспомним, что сетевые ресурсы организованы в виде дерева: на самом верхнем уровне идут домены и рабочие группы, затем сервера (компьютеры), затем ресурсы, предоставляемые серверами. Таким образом, вопрос немного видоизменяется: как получить дерево сетевых ресурсов.
Для этого используется тройка функций WNetOpenEnum, WNetEnumResource и WNetCloseEnum, в чeм-то напоминающая FindFirst, FindNext и FindClose.
Единицей хранения информации об узле дерева сетевых ресурсов является структура типа TNetResource.
TNetResource = packed record dwScope: DWORD; dwType: DWORD; dwDisplayType: DWORD; dwUsage: DWORD; lpLocalName: PAnsiChar; lpRemoteName: PAnsiChar; lpComment: PAnsiChar; lpProvider: PAnsiChar; end;
function WNetOpenEnum(dwScope, dwType, dwUsage: DWORD;
lpNetResource: PNetResource; var lphEnum: THandle): DWORD; stdcall;
Итак, функция, непосредственно читающая данные о сетевых ресурсах, называется WNetEnumResource.
function WNetEnumResource(hEnum: THandle; var lpcCount: DWORD;
lpBuffer: Pointer; var lpBufferSize: DWORD): DWORD; stdcall;
Во втором случае lpBufferSize должна содержать значение, меньшее, чем размер одной структуры TNetResource — тогда WNetEnumResource запишет в эту переменную требуемый размер массива в байтах.
Давайте рассмотрим первый способ на примере:
type TNetEnumResourcesCallback = procedure(NetResource: TNetResource);
procedure NetEnumResources(Root: PNetResource; Proc: TNetEnumResourcesCallback);
const MAX_RES = 16; type PResources = ^TResources; TResources = array[0..MAX_RES-1] of TNetResource;
var hEnum: THandle; Count: Integer; Res: Integer; Resources: PResources; BufferSize: Integer; I: Integer; sbegin // Открываем доступ к перечню сетевых ресурсов Res := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, lpNetResource, hEnum); if NO_ERROR <> Res then Exit; // Массив, в который читаются сетевые ресурсы BufferSize := SizeOf(TResources); GetMem(Resources, BufferSize); while True do begin // Загружаем перечень ресурсов в массив
// Если возникла ошибка, значит, ресурсов больше нет --- покидаем цикл Count := MAX_RES; Res := WNetEnumResource(hEnum, Count, Resources, BufferSize); if (Res <> NO_ERROR) and (Res <> ERROR_MORE_DATA) then Break; // В противном случае копируем сетевые ресурсы... for I := 0 to Count - 1 do begin Proc(Resources^[I]); if (Resources^[I].dwUsage and RESOURCEUSAGE_CONTAINER) <> 0 then NetEnumResources(@(Resources^[I]), Proc); end;
end;
FreeMem(Resources);
// Закрываем доступ WNetCloseEnum(hEnum); end;