Работа с локальной сетью
Преобразование IPAddres(LongInt) в привычное xxx.xxx.xxx.xxx
Обязательно указывать в uses модуль WinSock......
function Ip2String(Ip_address:longint):string;
begin
ip_address:=winsock.ntohl(ip_address);
result:= inttostr(ip_address shr 24)+'.'+
inttostr((ip_address shr 16) and $ff)+'.'+
inttostr((ip_address shr 8) and $ff)+'.'+
inttostr(ip_address and $ff);
end;
| Дополнение: |
В части преобразования IP адреса в строку, автор пошел по пути изобретения велосипеда. В winsock уже есть специальные функции для преобразования адресов.
function inet_ntoa(inaddr: TInAddr): PChar;
Функция предназначена для получения строкового представления IP адреса в
формате (a.b.c.d).
var
s : string;
L : longint;
.....
L := 12345678;
s := inet_ntoa( TInAddr(L));
.....
function inet_addr(cp: PChar): u_long; stdcall;
Функция предназначена для получения двоичного IP адреса из его строкового
представления (в любом виде, допустимом для IP адресов).
var
s : string;
l : longint;
...
s := '127.0.0.1';
l := inet_addr( PChar(s));
...
1.Получить список пользователей, подключенных
к сети.
unit NetUtils;
interface
uses Windows, Classes;
function GetContainerList(ListRoot:PNetResource):TList;
Type
{$H+}
PNetRes = ^TNetRes;
TNetRes = Record
dwScope : Integer;
dwType : Integer;
dwDisplayType : Integer;
dwUsage : Integer;
LocalName : String;
RemoteName : String;
Comment : String;
Provider : String;
End;
{H-}
implementation
uses SysUtils;
type
PnetResourceArr = ^TNetResource;
function GetContainerList(ListRoot:PNetResource):TList;
{возвращает список сетевых имён с подуровня ListRoot, каждый
элемент списка TList - это PNetRec, где поле RemoteName определяет
соответственно сетевое имя элемента списка. Если ListRoot=nil, то
возвращается самый верхний уровень типа:
1. Microsoft Windows Network
2. Novell Netware Network
Чтобы получить список доменов сети Microsoft, нужно вызвать эту
функцию второй раз, передав ей в качестве параметра,
соответствующий элемент списка, полученного при первом её вызове.
Чтобы получить список компьютеров домена - вызвать третий раз...}
{Единственное, я не знаю как узнать имя текущего домена.}
Var
TempRec : PNetRes;
Buf : Pointer;
Count,
BufSize,
Res : DWORD;
lphEnum : THandle;
p : PNetResourceArr;
i : SmallInt;
NetworkList : TList;
Begin
NetworkList := TList.Create;
Result:=nil;
BufSize := 8192;
GetMem(Buf, BufSize);
Try
Res := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
RESOURCEUSAGE_CONTAINER{0}, ListRoot,lphEnum);
{в результате получаем ссылку lphEnum}
If Res <> 0 Then Raise Exception(Res);
Count := $FFFFFFFF; {требуем выдать столько записей в
список, сколько есть}
Res := WNetEnumResource(lphEnum, Count, Buf, BufSize); {в буфере Buf - списочек
в виде массива указателей на структуры типа TNetResourceArr
а в Count - число этих структур}
If Res = ERROR_NO_MORE_ITEMS Then Exit;
If (Res <> 0) Then Raise Exception(Res);
P := PNetResourceArr(Buf);
For I := 0 To Count - 1 Do
Begin //Требуется копирование из буфера, так как он
New(TempRec); //действителен только до следующего вызова функций группы WNet
TempRec^.dwScope := P^.dwScope;
TempRec^.dwType := P^.dwType ;
TempRec^.dwDisplayType := P^.dwDisplayType ;
TempRec^.dwUsage := P^.dwUsage ;
TempRec^.LocalName := StrPas(P^.lpLocalName); {имеются ввиду вот эти указатели}
TempRec^.RemoteName := StrPas(P^.lpRemoteName); {в смысле - строки PChar}
TempRec^.Comment := StrPas(P^.lpComment);
TempRec^.Provider := StrPas(P^.lpProvider);
NetworkList.Add(TempRec);
Inc(P);
End;
Res := WNetCloseEnum(lphEnum);
{а следующий вызов - вот он!}
If Res <> 0 Then Raise Exception(Res);
Result:=NetWorkList;
Finally
FreeMem(Buf);
End;
End;
end.
1.Получить список ресурсов, подключенных к сети.
Пример этот я нашла на Борландовской конференции. Пример работает, но в сети с доменной структурой выдает сообщение об ошибке, хотя домены все же определяет. Если у кого дойдут руки разобраться, пришлите, пожалуйста, Ваш вариант.
Автор: Brad Stowers
2.Сканирование доменов
Переменная List заполняется списком доменов.
Функция возвращает код ошибки обращения к сети.
Function FillNetLevel(xxx: PNetResource; list: TStrings) : Word;
Type
PNRArr = ^TNRArr;
TNRArr = array[0..59] of TNetResource;
Var
x: PNRArr;
tnr: TNetResource;
I : integer;
EntrReq,
SizeReq,
twx: Integer;
WSName: string;
begin
Result := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY,
RESOURCEUSAGE_CONTAINER, xxx, twx);
If Result = ERROR_NO_NETWORK Then Exit;
if Result = NO_ERROR then
begin
New(x);
EntrReq := 1;
SizeReq := SizeOf(TNetResource)*59;
while (twx <> 0) and
(WNetEnumResource(twx, EntrReq, x, SizeReq) <> ERROR_NO_MORE_ITEMS) do
begin
For i := 0 To EntrReq - 1 do
begin
Move(x^[i], tnr, SizeOf(tnr));
case tnr.dwDisplayType of
RESOURCEDISPLAYTYPE_DOMAIN:
begin
if tnr.lpRemoteName <> '' then
WSName:= tnr.lpRemoteName
else WSName:= tnr.lpComment;
list.Add(WSName);
end;
else FillNetLevel(@tnr, list);
end;
end;
end;
Dispose(x);
WNetCloseEnum(twx);
end;
end;