|
Работа с локальной сетью |
::..::..:: |
Преобразование 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));
...
Получить список пользователей, подключенных к сети.
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.
Сканирование доменов
Переменная 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;
Как найти все компьютеры в рабочей группе?
var
Computer : Array[1..500] of String[25];
ComputerCount : Integer;
procedure FindAllComputers(Workgroup: String);
Var
EnumHandle : THandle;
WorkgroupRS : TNetResource;
Buf : Array[1..500] of TNetResource;
BufSize : Integer;
Entries : Integer;
Result : Integer;
begin
ComputerCount := 0;
Workgroup := Workgroup + #0;
FillChar(WorkgroupRS, SizeOf(WorkgroupRS) , 0);
With WorkgroupRS do begin
dwScope := 2;
dwType := 3;
dwDisplayType := 1;
dwUsage := 2;
lpRemoteName := @Workgroup[1];
end;
WNetOpenEnum( RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0,
@WorkgroupRS, EnumHandle );
Repeat
Entries := 1;
BufSize := SizeOf(Buf);
Result :=
WNetEnumResource( EnumHandle, Entries, @Buf, BufSize );
If (Result = NO_ERROR) and (Entries = 1) then begin
Inc( ComputerCount );
Computer[ ComputerCount ] := StrPas(Buf[1].lpRemoteName);
end;
Until (Entries <> 1) or (Result <> NO_ERROR);
WNetCloseEnum( EnumHandle );
end; { Find All Computers }
Как определить, подключен ли компьютер к Интернет (dial-up)?
Function CheckRAS: boolean;
const MaxEntries = 100;
var
BufSize : Integer;
NumEntries: Integer;
Entries : Array[1..MaxEntries] of TRasConn;
Begin
Entries[1].dwSize := SizeOf(TRasConn);
Bufsize:=SizeOf(TRasConn)*MaxEntries;
FillChar(Stat, Sizeof(TRasConnStatus), 0);
RasEnumConnections(@Entries[1], BufSize, NumEntries);
if numentries > 0 then result:=true
else result:=false;
End;
Подключение сетевого диска.
Если возникла необходимость, чтобы Ваше приложение самостоятельно подключало
сетевой ресурс, то это можно сделать двумя способами:
вызвать стандартный диалог подключения ресурса либо использоваться следующий
код.
//Пример открытия стандартного диалога
procedure TForm1.Button1Click(Sender: TObject);
begin
WNetConnectionDialog(Handle,RESOURCETYPE_DISK)
end;
//Так же можно подключить и принтер
procedure TForm1.Button1Click(Sender: TObject);
begin
WNetConnectionDialog(Handle,RESOURCETYPE_PRINT)
end;
//Либо можно использовать следующий код
procedure TForm1.Button2Click(Sender: TObject);
var
NetResource: TNetResource;
begin
{ заполняем структуру TNetResource }
NetResource.dwType := RESOURCETYPE_DISK;
NetResource.lpLocalName := 'S:';
NetResource.lpRemoteName := '\\myserver\public';
NetResource.lpProvider := '';
{ подключаем сетевой ресурс, используя структуру TNetResource }
If ( WNetAddConnection2(NetResource,'', {Password (if needed) or empty} '',
{User name (if needed) or empty}
CONNECT_UPDATE_PROFILE)<>NO_ERROR) Then
Raise Excepcion.Create('unable to map drive')
//так же существуют другие константы для определения возникшей ошибки
//ERROR_ACCESS_DENIED, ERROR_ALREADY_ASSIGNED, и
т.д.
end;
//Так же можно и отключить сетевой ресурс...
procedure TForm1.Button2Click(Sender: TObject);
begin
if WNetCancelConnection2( 'S:',0,TRUE) <> NO_ERROR then
Raise Exception.create('Error disconnecting map drive');
//соответственно можно использовать другие константы для определения ошибки
//ERROR_DEVICE_IN_USE, ERROR_NOT_CONNECTED,
и т.д.
end; Разместил
Razer | |
|
| | | | | | |
|