1282 lines
39 KiB
ObjectPascal
1282 lines
39 KiB
ObjectPascal
|
{*******************************************************}
|
||
|
{ }
|
||
|
{ Network Configuration Class }
|
||
|
{ }
|
||
|
{ }
|
||
|
{ Copyright (c) 2016-2021 Michal Mutl }
|
||
|
{ }
|
||
|
{*******************************************************}
|
||
|
|
||
|
{$INCLUDE Compilers.inc}
|
||
|
|
||
|
unit MiTeC_NCC;
|
||
|
|
||
|
interface
|
||
|
|
||
|
uses {$IFDEF RAD9PLUS}
|
||
|
WinAPI.Windows, System.SysUtils, System.Classes, WinAPI.WinSock,
|
||
|
{$ELSE}
|
||
|
Windows, SysUtils, Classes, WinSock,
|
||
|
{$ENDIF}
|
||
|
MiTeC_Windows, MiTeC_NetUtils;
|
||
|
|
||
|
{$IFDEF FPC}
|
||
|
const
|
||
|
// WinSock 2 extension -- manifest constants for shutdown()
|
||
|
{$EXTERNALSYM SD_RECEIVE}
|
||
|
SD_RECEIVE = 0;
|
||
|
{$EXTERNALSYM SD_SEND}
|
||
|
SD_SEND = 1;
|
||
|
{$EXTERNALSYM SD_BOTH}
|
||
|
SD_BOTH = 2;
|
||
|
{$ENDIF}
|
||
|
type
|
||
|
TNodeType = (ntUnknown, ntBroadcast, ntPeerToPeer, ntMixed, ntHybrid);
|
||
|
|
||
|
TAdapterType = (atOther, atEthernet, atTokenRing, atFDDI, atPPP, atLoopback,
|
||
|
atATM, atIEEE80211, atTunnel, atIEEE1394, atIEEE80216_WMAN,
|
||
|
atWWANPP, atWWANPP2);
|
||
|
|
||
|
TAdapterOperationalStatus = (aosNonOperational, aosUnreachable, aosDisconnected, aosConnecting, aosConnected, aosOperational);
|
||
|
|
||
|
TAdapterAdminStatus = (aasUnknown, aasUp, aasDown, aasTesting);
|
||
|
|
||
|
TAdapter = record
|
||
|
Description,
|
||
|
Name,
|
||
|
Alias,
|
||
|
MACAddress: string;
|
||
|
MaxSpeed: UInt64;
|
||
|
MTU: Cardinal;
|
||
|
Typ: TAdapterType;
|
||
|
AdminStatus: TAdapterAdminStatus;
|
||
|
OperStatus: TAdapterOperationalStatus;
|
||
|
DHCPEnabled,
|
||
|
DNSEnabled,
|
||
|
HaveWINS,
|
||
|
NETBIOSEnabled,
|
||
|
IPv4Enabled,
|
||
|
IPv6Enabled: boolean;
|
||
|
IPv4Address,
|
||
|
IPv6Address,
|
||
|
Gateways_v4,
|
||
|
Gateways_v6,
|
||
|
DHCPServers_v4,
|
||
|
DHCPServers_v6,
|
||
|
PrimaryWINS_v4,
|
||
|
PrimaryWINS_v6,
|
||
|
SecondaryWINS,
|
||
|
DNSServers_v4,
|
||
|
DNSServers_v6: TStringList;
|
||
|
DNSSuffix: string;
|
||
|
IntfIdx: Cardinal;
|
||
|
_Typ,
|
||
|
_Status: Cardinal;
|
||
|
_ImageIndex: Integer;
|
||
|
_Mark: Boolean;
|
||
|
end;
|
||
|
|
||
|
TAdapterList = array of TAdapter;
|
||
|
|
||
|
TAddressTypes = (atPrimary, atDynamic, atDisconnected, atDeleted, atTransient);
|
||
|
|
||
|
TAddressType = set of TAddressTypes;
|
||
|
|
||
|
TAddressRecord = record
|
||
|
IP,
|
||
|
Mask: string;
|
||
|
Physical: string;
|
||
|
IntfIdx: Cardinal;
|
||
|
Typ: TAddressType;
|
||
|
ARPType: Cardinal;
|
||
|
end;
|
||
|
|
||
|
TAddressTable = array of TAddressRecord;
|
||
|
|
||
|
TNetworkConfiguration = class
|
||
|
private
|
||
|
FAdapters: TAdapterList;
|
||
|
FAT,
|
||
|
FARP: TAddressTable;
|
||
|
FProxy: boolean;
|
||
|
FRouting: boolean;
|
||
|
FDNS: boolean;
|
||
|
FHost: string;
|
||
|
FDomain: string;
|
||
|
FDNSSuf: string;
|
||
|
FDNSList4,FDNSList6,FIL: TStrings;
|
||
|
FNode: TNodeType;
|
||
|
FDHCPScope: string;
|
||
|
FBII: Cardinal;
|
||
|
FIPData: TIPData;
|
||
|
FRefreshing: boolean;
|
||
|
FIA: boolean;
|
||
|
procedure ClearList;
|
||
|
function GetAdapter(Index: Word): TAdapter;
|
||
|
function GetAdapterCount: Word;
|
||
|
function Add(ARecord: TAdapter): Integer;
|
||
|
function GetAddrRec(Index: Word): TAddressRecord;
|
||
|
function GetAddrRecCount: Word;
|
||
|
function GetCurrentIPv4: string;
|
||
|
function GetCurrentMAC: string;
|
||
|
function GetARPRec(Index: Word): TAddressRecord;
|
||
|
function GetARPRecCount: Word;
|
||
|
function GetCurrentNet: string;
|
||
|
function GetAdapterImageIndex(Index: Word): integer;
|
||
|
function GetAdapterMark(Index: Word): boolean;
|
||
|
procedure SetAdapterMark(Index: Word; const Value: boolean);
|
||
|
procedure SetAdapterImageIndex(Index: Word; const Value: integer);
|
||
|
function GetCurrentAdapterName: string;
|
||
|
function GetCurrentIPv6: string;
|
||
|
public
|
||
|
class function GetSubnetMask(AIP: string): string;
|
||
|
class function SetIP(AIntfIdx: Cardinal; AStatic: Boolean; AIPv4,AMask,AGateway: string): Int64;
|
||
|
class function SetDNS(AIntfIdx: Cardinal; AStatic: Boolean; APreferred,AAlternate: string): Int64;
|
||
|
class function IsTCPPortOpen(const AIPv4: string; APort: Word; ATimeout: Cardinal = INFINITE {ms}): Boolean;
|
||
|
class function IsUDPPortOpen(const AIPv4: string; APort: Word; ATimeout: Cardinal = INFINITE {ms}): Boolean;
|
||
|
class function Ping(const AIPv4: string; ATTL, ARetries: byte; ATimeout: Cardinal): integer;
|
||
|
class function InternetAccessAvailable: boolean;
|
||
|
|
||
|
constructor Create;
|
||
|
destructor Destroy; override;
|
||
|
procedure Clear;
|
||
|
procedure RefreshData;
|
||
|
function FindAdapter(AName: string): Integer; overload;
|
||
|
function FindAdapter(AIntfIdx: Cardinal): Integer; overload;
|
||
|
function FindAddress(AIP: string): Integer; overload;
|
||
|
function FindAddress(AIntfIdx: Cardinal): Integer; overload;
|
||
|
function FindFirstOperational: Integer;
|
||
|
function FindFirstOperationalIntfIdx: Cardinal;
|
||
|
procedure GetTraffic(AIntfIdx: Cardinal; var AIn,AOut: UInt64);
|
||
|
property Refreshing: boolean read FRefreshing;
|
||
|
property Adapter[Index: Word]: TAdapter read GetAdapter;
|
||
|
property AdapterImageIndex[Index: Word]: integer read GetAdapterImageIndex write SetAdapterImageIndex;
|
||
|
property AdapterMark[Index: Word]: boolean read GetAdapterMark write SetAdapterMark;
|
||
|
property AdapterCount: Word read GetAdapterCount;
|
||
|
property AddressRecord[Index: Word]: TAddressRecord read GetAddrRec;
|
||
|
property AddressRecordCount: Word read GetAddrRecCount;
|
||
|
property ARPRecord[Index: Word]: TAddressRecord read GetARPRec;
|
||
|
property ARPRecordCount: Word read GetARPRecCount;
|
||
|
property HostName: string read FHost;
|
||
|
property DomainName: string read FDomain;
|
||
|
property ProxyEnabled: boolean read FProxy;
|
||
|
property RoutingEnabled: boolean read FRouting;
|
||
|
property DNSEnabled: boolean read FDNS;
|
||
|
property PrimaryDNSSuffix: string read FDNSSuf;
|
||
|
property DHCPScopeName: string read FDHCPScope;
|
||
|
property DNSServers_v4: TStrings read FDNSList4;
|
||
|
property DNSServers_v6: TStrings read FDNSList6;
|
||
|
property NodeType: TNodeType read FNode;
|
||
|
property BestInterfaceIdx: Cardinal read FBII;
|
||
|
property CurrentIPv4: string read GetCurrentIPv4;
|
||
|
property CurrentIPv6: string read GetCurrentIPv6;
|
||
|
property CurrentMAC: string read GetCurrentMAC;
|
||
|
property CurrentNetwork: string read GetCurrentNet;
|
||
|
property CurrentAdapterName: string read GetCurrentAdapterName;
|
||
|
property InternetAccess: boolean read FIA write FIA;
|
||
|
end;
|
||
|
|
||
|
const
|
||
|
NodeTypes: array[TNodeType] of string = ('Unknown','Broadcast','Peer-To-Peer','Mixed','Hybrid');
|
||
|
|
||
|
AdapterTypes: array[TAdapterType] of string = ('Other',
|
||
|
'Ethernet',
|
||
|
'Token Ring',
|
||
|
'FDDI',
|
||
|
'PPP',
|
||
|
'Loopback',
|
||
|
'ATM',
|
||
|
'IEEE 802.11 wireless',
|
||
|
'Tunnel encapsulation',
|
||
|
'IEEE 1394 (Firewire) high performance serial bus',
|
||
|
'Mobile broadband for WiMax',
|
||
|
'Mobile broadband for GSM',
|
||
|
'Mobile broadband for CDMA');
|
||
|
|
||
|
AdapterOperationalStatus: array[TAdapterOperationalStatus] of string = ('Non Operational',
|
||
|
'Unreachable',
|
||
|
'Disconnected',
|
||
|
'Connecting',
|
||
|
'Connected',
|
||
|
'Operational');
|
||
|
|
||
|
implementation
|
||
|
|
||
|
uses {$IFDEF RAD9PLUS}
|
||
|
WinAPI.ActiveX, System.Win.ComObj, System.Variants, WinApi.WinInet,
|
||
|
{$ELSE}
|
||
|
ActiveX, ComObj, Variants, WinInet,
|
||
|
{$ENDIF}
|
||
|
MiTeC_IPTypes, MiTeC_IpHlpAPI, MiTeC_Ws2_32, MiTeC_IcmpAPI;
|
||
|
|
||
|
function Swap32(const Figure: Integer): Integer;
|
||
|
var
|
||
|
ByteArray: array [1..4] of Byte absolute Figure;
|
||
|
begin
|
||
|
Result:=ByteArray[1]*$1000000+ByteArray[2]*$10000+ByteArray[3]*$100+ByteArray[4];
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.Add(ARecord: TAdapter): Integer;
|
||
|
begin
|
||
|
SetLength(FAdapters,Length(FAdapters)+1);
|
||
|
Result:=High(FAdapters);
|
||
|
FAdapters[Result]:=ARecord;
|
||
|
end;
|
||
|
|
||
|
procedure TNetworkConfiguration.Clear;
|
||
|
begin
|
||
|
ClearList;
|
||
|
Finalize(FAT);
|
||
|
Finalize(FARP);
|
||
|
FProxy:=False;
|
||
|
FRouting:=False;
|
||
|
FDNS:=False;
|
||
|
FHost:='';
|
||
|
FDomain:='';
|
||
|
FDNSList4.Clear;
|
||
|
FDNSList6.Clear;
|
||
|
FNode:=ntUnknown;
|
||
|
FDHCPScope:='';
|
||
|
FDNSSuf:='';
|
||
|
FBII:=0;
|
||
|
FIL.Clear;
|
||
|
end;
|
||
|
|
||
|
procedure TNetworkConfiguration.ClearList;
|
||
|
var
|
||
|
i: Integer;
|
||
|
begin
|
||
|
for i:=0 to High(FAdapters) do begin
|
||
|
FAdapters[i].IPv4Address.Free;
|
||
|
FAdapters[i].IPv6Address.Free;
|
||
|
FAdapters[i].Gateways_v4.Free;
|
||
|
FAdapters[i].Gateways_v6.Free;
|
||
|
FAdapters[i].DHCPServers_v4.Free;
|
||
|
FAdapters[i].DHCPServers_v6.Free;
|
||
|
FAdapters[i].PrimaryWINS_v4.Free;
|
||
|
FAdapters[i].PrimaryWINS_v6.Free;
|
||
|
FAdapters[i].SecondaryWINS.Free;
|
||
|
FAdapters[i].DNSServers_v4.Free;
|
||
|
FAdapters[i].DNSServers_v6.Free;
|
||
|
Finalize(FAdapters[i]);
|
||
|
end;
|
||
|
Finalize(FAdapters);
|
||
|
end;
|
||
|
|
||
|
constructor TNetworkConfiguration.Create;
|
||
|
begin
|
||
|
Finalize(FIPData);
|
||
|
FDNSList4:=TStringList.Create;
|
||
|
FDNSList6:=TStringList.Create;
|
||
|
FIL:=TStringList.Create;
|
||
|
InitIpHlpAPI;
|
||
|
FRefreshing:=False;
|
||
|
Clear;
|
||
|
end;
|
||
|
|
||
|
destructor TNetworkConfiguration.Destroy;
|
||
|
begin
|
||
|
Clear;
|
||
|
FDNSList4.Free;
|
||
|
FDNSList6.Free;
|
||
|
FIL.Free;
|
||
|
inherited;
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.FindAdapter(AName: string): Integer;
|
||
|
var
|
||
|
i: Integer;
|
||
|
begin
|
||
|
Result:=-1;
|
||
|
for i:=0 to High(FAdapters) do
|
||
|
if SameText(FAdapters[i].Name,AName) then begin
|
||
|
Result:=i;
|
||
|
Break;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.FindAdapter(AIntfIdx: Cardinal): Integer;
|
||
|
var
|
||
|
i: Integer;
|
||
|
begin
|
||
|
Result:=-1;
|
||
|
for i:=0 to High(FAdapters) do
|
||
|
if (FAdapters[i].IntfIdx=AIntfIdx) then begin
|
||
|
Result:=i;
|
||
|
Break;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.FindAddress(AIP: string): Integer;
|
||
|
var
|
||
|
i: Integer;
|
||
|
begin
|
||
|
Result:=-1;
|
||
|
for i:=0 to High(FAT) do
|
||
|
if SameText(FAT[i].IP,AIP) then begin
|
||
|
Result:=i;
|
||
|
Break;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.FindAddress(AIntfIdx: Cardinal): Integer;
|
||
|
var
|
||
|
i: Integer;
|
||
|
begin
|
||
|
Result:=-1;
|
||
|
for i:=0 to High(FAT) do
|
||
|
if (FAT[i].IntfIdx=AIntfIdx) then begin
|
||
|
Result:=i;
|
||
|
Break;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.FindFirstOperational: Integer;
|
||
|
var
|
||
|
i: Integer;
|
||
|
begin
|
||
|
Result:=-1;
|
||
|
for i:=0 to High(FAdapters) do
|
||
|
if (FAdapters[i].OperStatus=aosOperational) then begin
|
||
|
Result:=i;
|
||
|
Break;
|
||
|
end;
|
||
|
if Result=-1 then
|
||
|
for i:=0 to High(FAdapters) do
|
||
|
if (FAdapters[i].IPv4Address.Count>0) and (StrToIPv4(FAdapters[i].IPv4Address[0]).Value>0) then begin
|
||
|
Result:=i;
|
||
|
Break;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.FindFirstOperationalIntfIdx: Cardinal;
|
||
|
var
|
||
|
idx: Integer;
|
||
|
begin
|
||
|
Result:=0;
|
||
|
idx:=FindFirstOperational;
|
||
|
if idx>-1 then
|
||
|
Result:=FAdapters[idx].IntfIdx;
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.GetAdapter(Index: Word): TAdapter;
|
||
|
begin
|
||
|
Result:=FAdapters[Index];
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.GetAdapterCount: Word;
|
||
|
begin
|
||
|
Result:=Length(FAdapters);
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.GetAdapterImageIndex(Index: Word): integer;
|
||
|
begin
|
||
|
Result:=FAdapters[Index]._ImageIndex;
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.GetAdapterMark(Index: Word): boolean;
|
||
|
begin
|
||
|
Result:=FAdapters[Index]._Mark;
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.GetAddrRec(Index: Word): TAddressRecord;
|
||
|
begin
|
||
|
Result:=FAT[Index];
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.GetAddrRecCount: Word;
|
||
|
begin
|
||
|
Result:=Length(FAT);
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.GetARPRec(Index: Word): TAddressRecord;
|
||
|
begin
|
||
|
Result:=FARP[Index];
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.GetARPRecCount: Word;
|
||
|
begin
|
||
|
Result:=Length(FARP);
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.GetCurrentAdapterName: string;
|
||
|
var
|
||
|
r,n: Cardinal;
|
||
|
idx: integer;
|
||
|
begin
|
||
|
Result:='';
|
||
|
n:=0;
|
||
|
r:=GetBestInterface(inet_addr(PAnsiChar('8.8.8.8')),n);
|
||
|
if Length(FAT)=0 then
|
||
|
RefreshData;
|
||
|
if r=NO_ERROR then
|
||
|
FBII:=n
|
||
|
else
|
||
|
FBII:=FindFirstOperationalIntfIdx;
|
||
|
idx:=FindAdapter(FBII);
|
||
|
if idx>-1 then
|
||
|
Result:=FAdapters[idx].Name;
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.GetCurrentIPv4: string;
|
||
|
var
|
||
|
r,n: Cardinal;
|
||
|
idx: integer;
|
||
|
begin
|
||
|
Result:='';
|
||
|
n:=0;
|
||
|
r:=GetBestInterface(inet_addr(PAnsiChar('8.8.8.8')),n);
|
||
|
if Length(FAT)=0 then
|
||
|
RefreshData;
|
||
|
if r=NO_ERROR then
|
||
|
FBII:=n
|
||
|
else
|
||
|
FBII:=FindFirstOperationalIntfIdx;
|
||
|
idx:=FindAddress(FBII);
|
||
|
if idx>-1 then
|
||
|
Result:=FAT[idx].IP;
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.GetCurrentIPv6: string;
|
||
|
var
|
||
|
r,n: Cardinal;
|
||
|
idx: integer;
|
||
|
begin
|
||
|
Result:='';
|
||
|
n:=0;
|
||
|
r:=GetBestInterface(inet_addr(PAnsiChar('8.8.8.8')),n);
|
||
|
if Length(FAT)=0 then
|
||
|
RefreshData;
|
||
|
if r=NO_ERROR then
|
||
|
FBII:=n
|
||
|
else
|
||
|
FBII:=FindFirstOperationalIntfIdx;
|
||
|
idx:=FindAdapter(FBII);
|
||
|
if (idx>-1) and FAdapters[idx].IPv6Enabled and (FAdapters[idx].IPv6Address.Count>0) then
|
||
|
Result:=FAdapters[idx].IPv6Address[0];
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.GetCurrentMAC: string;
|
||
|
var
|
||
|
r,n: Cardinal;
|
||
|
idx: integer;
|
||
|
begin
|
||
|
Result:='';
|
||
|
n:=0;
|
||
|
r:=GetBestInterface(inet_addr(PAnsiChar('8.8.8.8')),n);
|
||
|
if Length(FAT)=0 then
|
||
|
RefreshData;
|
||
|
if r=NO_ERROR then
|
||
|
FBII:=n
|
||
|
else
|
||
|
FBII:=FindFirstOperationalIntfIdx;
|
||
|
idx:=FindAdapter(FBII);
|
||
|
if idx>-1 then
|
||
|
Result:=FAdapters[idx].MACAddress;
|
||
|
end;
|
||
|
|
||
|
function TNetworkConfiguration.GetCurrentNet: string;
|
||
|
var
|
||
|
r,n: Cardinal;
|
||
|
idx: integer;
|
||
|
begin
|
||
|
Result:='';
|
||
|
n:=0;
|
||
|
r:=GetBestInterface(inet_addr(PAnsiChar('8.8.8.8')),n);
|
||
|
if Length(FAT)=0 then
|
||
|
RefreshData;
|
||
|
if r=NO_ERROR then
|
||
|
FBII:=n
|
||
|
else
|
||
|
FBII:=FindFirstOperationalIntfIdx;
|
||
|
idx:=FindAdapter(FBII);
|
||
|
if idx>-1 then
|
||
|
Result:=FAdapters[idx].Alias;
|
||
|
end;
|
||
|
|
||
|
class function TNetworkConfiguration.GetSubnetMask(AIP: string): string;
|
||
|
var
|
||
|
ip: TIPv4;
|
||
|
begin
|
||
|
Result:='0.0.0.0';
|
||
|
ip:=StrToIPv4(AIP);
|
||
|
if ip.A in [1..126] then
|
||
|
Result:='255.0.0.0'
|
||
|
else if ip.A in [128..191] then
|
||
|
Result:='255.255.0.0'
|
||
|
else if ip.A in [192..223] then
|
||
|
Result:='255.255.255.0';
|
||
|
end;
|
||
|
|
||
|
procedure TNetworkConfiguration.GetTraffic(AIntfIdx: Cardinal; var AIn,
|
||
|
AOut: UInt64);
|
||
|
var
|
||
|
Entry: TMIB_IFROW;
|
||
|
Entry2: TMIB_IFROW2;
|
||
|
begin
|
||
|
AIn:=0;
|
||
|
AOut:=0;
|
||
|
FillChar(Entry,SizeOf(Entry),0);
|
||
|
Entry.dwIndex:=AIntfIdx;
|
||
|
FillChar(Entry2,SizeOf(Entry2),0);
|
||
|
Entry2.InterfaceIndex:=AIntfIdx;
|
||
|
if Assigned(GetIfEntry2) and (GetIfEntry2(Entry2)=0) then begin
|
||
|
AIn:=Entry2.InOctets;
|
||
|
AOut:=Entry2.OutOctets;
|
||
|
end else if GetIfEntry(Entry)=0 then begin
|
||
|
AIn:=Entry.dwInOctets;
|
||
|
AOut:=Entry.dwOutOctets;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
class function TNetworkConfiguration.InternetAccessAvailable: boolean;
|
||
|
var
|
||
|
//f: Cardinal;
|
||
|
hs,hu: HInternet;
|
||
|
begin
|
||
|
//Result:=InternetGetConnectedState(@f,0);
|
||
|
//if Result and (f and INTERNET_CONNECTION_CONFIGURED>0) then begin
|
||
|
hs:=InternetOpen('test',INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);
|
||
|
try
|
||
|
hu:=InternetOpenURL(hs,'http://www.google.com',nil,0,0,0);
|
||
|
Result:=hu<>nil;
|
||
|
InternetCloseHandle(hu);
|
||
|
finally
|
||
|
InternetCloseHandle(hs);
|
||
|
end;
|
||
|
{end else
|
||
|
Result:=False;}
|
||
|
end;
|
||
|
|
||
|
class function TNetworkConfiguration.IsTCPPortOpen(const AIPv4: string; APort: Word; ATimeout: Cardinal = INFINITE): Boolean;
|
||
|
var
|
||
|
wsData: TWSAData;
|
||
|
hSocket: TSocket;
|
||
|
iVal: Integer;
|
||
|
iRes: Integer;
|
||
|
SockAddr: TSockAddr;
|
||
|
WrSet: TFDSet;
|
||
|
TimeVal: TTimeVal;
|
||
|
begin
|
||
|
Result:=False;
|
||
|
WSAStartup($0101, wsData);
|
||
|
try
|
||
|
hSocket:=Socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
|
||
|
if hSocket=INVALID_SOCKET then
|
||
|
Exit;
|
||
|
try
|
||
|
iVal:=1;
|
||
|
if ATimeout<>INFINITE then
|
||
|
{$R-}
|
||
|
if IOCtlSocket(hSocket,FIONBIO,iVal)=SOCKET_ERROR then
|
||
|
Exit;
|
||
|
FillChar(SockAddr,sizeof(SockAddr),0);
|
||
|
SockAddr.sin_family:=AF_INET;
|
||
|
SockAddr.sin_port:=htons(APort);
|
||
|
SockAddr.sin_addr:=IPv4ToInAddr(StrToIPv4(AIPv4));
|
||
|
iRes:=Connect(hSocket,SockAddr,sizeof(SockAddr));
|
||
|
if iRes<>SOCKET_ERROR then begin
|
||
|
if ATimeout=INFINITE then
|
||
|
Result:=True
|
||
|
else
|
||
|
Exit;
|
||
|
end;
|
||
|
if ATimeout<>INFINITE then begin
|
||
|
iRes:=WSAGetLastError;
|
||
|
if iRes<>WSAEWOULDBLOCK then
|
||
|
Exit;
|
||
|
TimeVal.tv_sec:=0;
|
||
|
TimeVal.tv_usec:=ATimeout*1000;
|
||
|
FD_ZERO(WrSet);
|
||
|
FD_SET(hSocket,WrSet);
|
||
|
Result:=Select(0,nil,@WrSet,nil,@TimeVal)=1;
|
||
|
end;
|
||
|
finally
|
||
|
Shutdown(hSocket,SD_BOTH);
|
||
|
CloseSocket(hSocket);
|
||
|
end;
|
||
|
finally
|
||
|
WSACleanup;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
class function TNetworkConfiguration.IsUDPPortOpen(const AIPv4: string;
|
||
|
APort: Word; ATimeout: Cardinal): Boolean;
|
||
|
var
|
||
|
wsData: TWSAData;
|
||
|
hSocket: TSocket;
|
||
|
iRes: Integer;
|
||
|
SockAddr: TSockAddr;
|
||
|
buf: array[0..1023] of ansichar;
|
||
|
wsabuf: TWsaBuf;
|
||
|
RecvOverlapped: WSAOVERLAPPED;
|
||
|
n,f: Cardinal;
|
||
|
hello: array[0..5] of ansichar;
|
||
|
begin
|
||
|
Result:=False;
|
||
|
hello[0]:='H';
|
||
|
hello[1]:='e';
|
||
|
hello[2]:='l';
|
||
|
hello[3]:='l';
|
||
|
hello[4]:='o';
|
||
|
hello[5]:=#0;
|
||
|
WSAStartup($0101, wsData);
|
||
|
try
|
||
|
hSocket:=Socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
|
||
|
if hSocket=INVALID_SOCKET then
|
||
|
Exit;
|
||
|
try
|
||
|
FillChar(SockAddr,sizeof(SockAddr),0);
|
||
|
SockAddr.sin_family:=AF_INET;
|
||
|
SockAddr.sin_port:=htons(APort);
|
||
|
SockAddr.sin_addr:=IPv4ToInAddr(StrToIPv4(AIPv4));
|
||
|
|
||
|
iRes:=Connect(hSocket,SockAddr,sizeof(SockAddr));
|
||
|
if iRes=SOCKET_ERROR then
|
||
|
Exit;
|
||
|
iRes:=send(hSocket,hello,sizeof(hello),0);
|
||
|
if iRes=SOCKET_ERROR then
|
||
|
Exit;
|
||
|
FillChar(RecvOverlapped,sizeof(RecvOverlapped),0);
|
||
|
RecvOverlapped.hEvent:=WSACreateEvent;
|
||
|
if RecvOverlapped.hEvent=0 then
|
||
|
Exit;
|
||
|
try
|
||
|
FillChar(buf,sizeof(buf),0);
|
||
|
wsabuf.len:=sizeof(buf);
|
||
|
wsabuf.buf:=@buf;
|
||
|
f:=0;
|
||
|
n:=0;
|
||
|
iRes:=WSARecv(hSocket,@wsabuf,1,n,f,@RecvOverlapped,nil);
|
||
|
if (iRes=SOCKET_ERROR) and (WSAGetLastError<>ERROR_IO_PENDING) then
|
||
|
Exit;
|
||
|
iRes:=WSAWaitForMultipleEvents(1,@RecvOverlapped.hEvent,True,ATimeout,True);
|
||
|
if iRes=WAIT_FAILED then
|
||
|
Exit;
|
||
|
if not WSAGetOverlappedResult(hSocket,@RecvOverlapped,n,False,f) then begin
|
||
|
Result:=WSAGetLastError=ERROR_IO_INCOMPLETE;
|
||
|
Exit;
|
||
|
end;
|
||
|
Result:=True;
|
||
|
WSAResetEvent(RecvOverlapped.hEvent);
|
||
|
finally
|
||
|
WSACloseEvent(RecvOverlapped.hEvent);
|
||
|
end;
|
||
|
finally
|
||
|
CloseSocket(hSocket);
|
||
|
end;
|
||
|
finally
|
||
|
WSACleanup;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
class function TNetworkConfiguration.Ping(const AIPv4: string; ATTL, ARetries: byte; ATimeout: Cardinal): integer;
|
||
|
var
|
||
|
ICMPFile: THandle;
|
||
|
ReplySize,NumResponses: Cardinal;
|
||
|
SendData: array[0..31] of AnsiChar;
|
||
|
ReplyBuffer: PICMP_ECHO_REPLY;
|
||
|
ioi: TIpOptionInformation;
|
||
|
i,j: Byte;
|
||
|
t: Cardinal;
|
||
|
begin
|
||
|
Result:=-1;
|
||
|
if ARetries<1 then
|
||
|
ARetries:=1;
|
||
|
t:=0;
|
||
|
j:=0;
|
||
|
|
||
|
SendData:='1234567890ABCDEFGHIJKLMNOPQRSTUV';
|
||
|
ioi.Ttl:=ATTL;
|
||
|
ioi.Tos:=0;
|
||
|
ioi.Flags:=0;
|
||
|
ioi.OptionsSize:=0;
|
||
|
ioi.OptionsData:=nil;
|
||
|
IcmpFile:=IcmpCreateFile;
|
||
|
if IcmpFile<>INVALID_HANDLE_VALUE then
|
||
|
try
|
||
|
ReplySize:=SizeOf(ICMP_ECHO_REPLY)+SizeOf(SendData)+8;
|
||
|
ReplyBuffer:=AllocMem(ReplySize);
|
||
|
try
|
||
|
for i:=0 to ARetries-1 do begin
|
||
|
ZeroMemory(ReplyBuffer,ReplySize);
|
||
|
NumResponses:=IcmpSendEcho(IcmpFile,IPv4ToInAddr(StrToIPv4(AIPv4)),@SendData,SizeOf(SendData),@ioi,ReplyBuffer,ReplySize,ATimeout);
|
||
|
if (NumResponses<>0) and (ReplyBuffer.Status=0) then begin
|
||
|
Inc(t,ReplyBuffer.RoundTripTime);
|
||
|
inc(j);
|
||
|
Result:=0;
|
||
|
end else if Result=-1 then
|
||
|
Result:=-integer(ReplyBuffer.Status);
|
||
|
end;
|
||
|
if (Result=0) and (j>0) then
|
||
|
Result:=Round(t/j)
|
||
|
else
|
||
|
Result:=-1;
|
||
|
finally
|
||
|
FreeMem(ReplyBuffer);
|
||
|
end;
|
||
|
finally
|
||
|
IcmpCloseHandle(IcmpFile);
|
||
|
end
|
||
|
end;
|
||
|
|
||
|
procedure TNetworkConfiguration.RefreshData;
|
||
|
var
|
||
|
aim: TIP_ADAPTER_INDEX_MAP;
|
||
|
ai, aiInitPtr: PIP_ADAPTER_INFO;
|
||
|
lastip,ip: PIP_ADDR_STRING;
|
||
|
aa,aaInitPtr: PIP_ADAPTER_ADDRESSES;
|
||
|
lastdns,dns: PIP_ADAPTER_DNS_SERVER_ADDRESS;
|
||
|
gw,lastgw: PIP_ADAPTER_GATEWAY_ADDRESS_LH;
|
||
|
wins,lastwins: PIP_ADAPTER_WINS_SERVER_ADDRESS_LH;
|
||
|
fua,lastfua: PIP_ADAPTER_UNICAST_ADDRESS;
|
||
|
Entry: TMIB_IFROW;
|
||
|
Entry2: TMIB_IFROW2;
|
||
|
IPAdrRow: TMIB_IPADDRROW;
|
||
|
IPNetRow: TMIB_IPNETROW;
|
||
|
np: PFixedInfo;
|
||
|
r,j,n: Cardinal;
|
||
|
Size: ulong;
|
||
|
A: TAdapter;
|
||
|
s: string;
|
||
|
pBuf,pb: PAnsiChar;
|
||
|
idx,i,k: Integer;
|
||
|
luid: NET_LUID;
|
||
|
alias: array[0..IF_MAX_STRING_SIZE] of char;
|
||
|
sa4: sockaddr_in;
|
||
|
sa6: TSockAddrIn6;
|
||
|
buf: array[0..255] of char;
|
||
|
begin
|
||
|
if FRefreshing then
|
||
|
Exit;
|
||
|
FIA:=InternetAccessAvailable;
|
||
|
Clear;
|
||
|
if InitIpHlpAPI then begin
|
||
|
FRefreshing:=True;
|
||
|
try
|
||
|
Size:=SizeOf(TFixedInfo);
|
||
|
np:=Allocmem(size);
|
||
|
try
|
||
|
r:=GetNetworkparams(np,Size);
|
||
|
while r=ERROR_BUFFER_OVERFLOW do begin
|
||
|
Reallocmem(np,size);
|
||
|
r:=GetNetworkparams(np,Size);
|
||
|
end;
|
||
|
|
||
|
if r=ERROR_SUCCESS then begin
|
||
|
case np^.NodeType of
|
||
|
BROADCAST_NODETYPE: FNode:=ntBroadcast;
|
||
|
PEER_TO_PEER_NODETYPE: FNode:=ntPeerToPeer;
|
||
|
MIXED_NODETYPE: FNode:=ntMixed;
|
||
|
HYBRID_NODETYPE: FNode:=ntHybrid;
|
||
|
else FNode:=ntUnknown;
|
||
|
end;
|
||
|
FDHCPScope:=string(np^.ScopeId);
|
||
|
if Assigned(np^.CurrentDnsServer) then
|
||
|
FDNSSuf:=string(np^.CurrentDnsServer.IPAddress.S)
|
||
|
else
|
||
|
FDNSSuf:='';
|
||
|
|
||
|
ip:=@(np^.DnsServerList);
|
||
|
FDNSList4.Clear;
|
||
|
repeat
|
||
|
s:=string(ip^.IPAddress.s);
|
||
|
FDNSList4.Add(s);
|
||
|
ip:=ip.Next;
|
||
|
until (not Assigned(ip)) or (s=string(ip^.IPAddress.s));
|
||
|
|
||
|
FHost:=string(np^.HostName);
|
||
|
FDomain:=string(np^.DomainName);
|
||
|
FProxy:=Boolean(np^.EnableProxy);
|
||
|
FRouting:=Boolean(np^.EnableRouting);
|
||
|
FDNS:=Boolean(np^.EnableDns);
|
||
|
end;
|
||
|
finally
|
||
|
if Assigned(np) then
|
||
|
FreeMem(np);
|
||
|
end;
|
||
|
|
||
|
size:=SizeOf(TIP_INTERFACE_INFO);
|
||
|
pBuf:=AllocMem(size);
|
||
|
try
|
||
|
r:=GetInterfaceInfo(PIP_INTERFACE_INFO(pBuf),size);
|
||
|
while(r=ERROR_INSUFFICIENT_BUFFER) do begin
|
||
|
size:=Size+SizeOf(TIP_INTERFACE_INFO);
|
||
|
ReallocMem(pBuf,size);
|
||
|
r:=GetInterfaceInfo(PIP_INTERFACE_INFO(pBuf),size);
|
||
|
end;
|
||
|
if(r=ERROR_SUCCESS) then begin
|
||
|
pb:=pBuf;
|
||
|
n:=PIP_INTERFACE_INFO(pb).NumAdapters;
|
||
|
if n>0 then begin
|
||
|
Inc(pb,SizeOf(integer));
|
||
|
for j:=1 to n do begin
|
||
|
aim:=PIP_ADAPTER_INDEX_MAP(pb)^;
|
||
|
s:=aim.Name;
|
||
|
s:=Trim(s);
|
||
|
idx:=Pos('}',s);
|
||
|
if idx>0 then
|
||
|
SetLength(s,idx);
|
||
|
FIL.Add(Format('%s=%d',[s,aim.Index]));
|
||
|
Inc(pb,SizeOf(Integer)+SizeOf(TIP_ADAPTER_INDEX_MAP));
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
finally
|
||
|
try FreeMem(pBuf) except end;
|
||
|
end;
|
||
|
|
||
|
size:=SizeOf(IP_ADAPTER_INFO);
|
||
|
aiInitPtr:=AllocMem(size);
|
||
|
try
|
||
|
r:=GetAdaptersInfo(aiInitPtr,size);
|
||
|
while(r=ERROR_BUFFER_OVERFLOW) do begin
|
||
|
size:=Size+SizeOf(IP_ADAPTER_INFO);
|
||
|
ReallocMem(aiInitPtr,size);
|
||
|
r:=GetAdaptersInfo(aiInitPtr,size);
|
||
|
end;
|
||
|
ai:=aiInitPtr;
|
||
|
if(r=ERROR_SUCCESS) then begin
|
||
|
while assigned(ai) do begin
|
||
|
FillChar(A,SizeOf(A),0);
|
||
|
A.IPv4Address:=TStringList.Create;
|
||
|
A.IPv6Address:=TStringList.Create;
|
||
|
A.Gateways_v4:=TStringList.Create;
|
||
|
A.Gateways_v6:=TStringList.Create;
|
||
|
A.DHCPServers_v4:=TStringList.Create;
|
||
|
A.DHCPServers_v6:=TStringList.Create;
|
||
|
A.PrimaryWINS_v4:=TStringList.Create;
|
||
|
A.PrimaryWINS_v6:=TStringList.Create;
|
||
|
A.SecondaryWINS:=TStringList.Create;
|
||
|
A.DNSServers_v4:=TStringList.Create;
|
||
|
A.DNSServers_v6:=TStringList.Create;
|
||
|
|
||
|
A.Name:=Trim(string(ai^.AdapterName));
|
||
|
A.Description:=Trim(string(ai^.Description));
|
||
|
A._Typ:=ai^.Type_;
|
||
|
case ai^.Type_ of
|
||
|
MIB_IF_OTHER_ADAPTERTYPE: A.Typ:=atOther;
|
||
|
MIB_IF_ETHERNET_ADAPTERTYPE: A.Typ:=atEthernet;
|
||
|
MIB_IF_TOKEN_RING_ADAPTERTYPE: A.Typ:=atTokenRing;
|
||
|
MIB_IF_FDDI_ADAPTERTYPE: A.Typ:=atFDDI;
|
||
|
MIB_IF_PPP_ADAPTERTYPE: A.Typ:=atPPP;
|
||
|
MIB_IF_LOOPBACK_ADAPTERTYPE: A.Typ:=atLoopback;
|
||
|
MIB_IF_ATM_ADAPTERTYPE,MIB_IF_TYPE_SLIP: A.Typ:=atATM;
|
||
|
MIB_IF_TYPE_IEEE80211: A.Typ:=atIEEE80211;
|
||
|
MIB_IF_TYPE_TUNNEL: A.Typ:=atTunnel;
|
||
|
MIB_IF_TYPE_IEEE1394: A.Typ:=atIEEE1394;
|
||
|
MIB_IF_TYPE_IEEE80216_WMAN: A.Typ:=atIEEE80216_WMAN;
|
||
|
MIB_IF_TYPE_WWANPP: A.Typ:=atWWANPP;
|
||
|
MIB_IF_TYPE_WWANPP2: A.Typ:=atWWANPP2;
|
||
|
end;
|
||
|
s:='';
|
||
|
if ai^.AddressLength>0 then begin
|
||
|
for j:=0 to ai^.AddressLength-1 do
|
||
|
s:=s+Format('%2.2x:',[ai^.Address[j]]);
|
||
|
SetLength(s,Length(s)-1);
|
||
|
end;
|
||
|
A.MACAddress:=s;
|
||
|
A.DHCPEnabled:=Boolean(ai^.DhcpEnabled);
|
||
|
A.HaveWINS:=Boolean(ai^.HaveWins);
|
||
|
|
||
|
ip:=@(ai^.IpAddressList);
|
||
|
repeat
|
||
|
lastip:=ip;
|
||
|
A.IPv4Address.Add(Format('%s=%s',[string(ip^.IPAddress.s),string(ip^.IpMask.s)]));
|
||
|
ip:=ip.Next;
|
||
|
until not Assigned(ip) or (lastip=ip);
|
||
|
|
||
|
ip:=@(ai^.GatewayList);
|
||
|
repeat
|
||
|
lastip:=ip;
|
||
|
A.Gateways_v4.Add(Format('%s=%s',[string(ip^.IPAddress.s),string(ip^.IpMask.s)]));
|
||
|
ip:=ip.Next;
|
||
|
until not Assigned(ip) or (lastip=ip);
|
||
|
|
||
|
ip:=@(ai^.DhcpServer);
|
||
|
repeat
|
||
|
lastip:=ip;
|
||
|
A.DHCPServers_v4.Add(Format('%s=%s',[string(ip^.IPAddress.s),string(ip^.IpMask.s)]));
|
||
|
ip:=ip.Next;
|
||
|
until not Assigned(ip) or (lastip=ip);
|
||
|
|
||
|
ip:=@(ai^.PrimaryWinsServer);
|
||
|
repeat
|
||
|
lastip:=ip;
|
||
|
A.PrimaryWINS_v4.Add(Format('%s=%s',[string(ip^.IPAddress.s),string(ip^.IpMask.s)]));
|
||
|
ip:=ip.Next;
|
||
|
until not Assigned(ip) or (lastip=ip);
|
||
|
|
||
|
ip:=@(ai^.SecondaryWinsServer);
|
||
|
repeat
|
||
|
lastip:=ip;
|
||
|
A.SecondaryWINS.Add(Format('%s=%s',[string(ip^.IPAddress.s),string(ip^.IpMask.s)]));
|
||
|
ip:=ip.Next;
|
||
|
until not Assigned(ip) or (lastip=ip);
|
||
|
|
||
|
s:='';
|
||
|
for k:=0 to A.IPv4Address.Count-1 do
|
||
|
for i:=0 to High(FIPData) do
|
||
|
if SameText(A.IPv4Address.Names[k],FIPData[i].IP4) then
|
||
|
s:=s+FIPData[i].IP6+',';
|
||
|
SetLength(s,Length(s)-1);
|
||
|
A.IPv6Address.CommaText:=s;
|
||
|
|
||
|
FillChar(Entry,SizeOf(Entry),0);
|
||
|
Entry.dwIndex:=ai.Index;
|
||
|
if GetIfEntry(Entry)=0 then begin
|
||
|
A.Name:=Entry.wszName;
|
||
|
A.Name:=Trim(A.Name);
|
||
|
A.MaxSpeed:=Entry.dwSpeed;
|
||
|
A.MTU:=Entry.dwMTU;
|
||
|
A.AdminStatus:=TAdapterAdminStatus(Entry.dwAdminStatus);
|
||
|
A._Status:=Entry.dwOperStatus;
|
||
|
A.OperStatus:=TAdapterOperationalStatus(Entry.dwOperStatus);
|
||
|
end;
|
||
|
|
||
|
FillChar(Entry2,SizeOf(Entry2),0);
|
||
|
Entry2.InterfaceIndex:=ai.Index;
|
||
|
if Assigned(GetIfEntry2) and (GetIfEntry2(Entry2)=0) then begin
|
||
|
A.Name:=Entry2.Description;
|
||
|
A.Name:=Trim(A.Name);
|
||
|
A.Alias:=Entry2.Alias;
|
||
|
A.Alias:=Trim(A.Alias);
|
||
|
A.MaxSpeed:=Entry2.TransmitLinkSpeed;
|
||
|
A.MTU:=Entry2.Mtu;
|
||
|
end;
|
||
|
|
||
|
if A.Name='' then
|
||
|
A.Name:=A.Description;
|
||
|
|
||
|
idx:=FIL.IndexOfName(A.Name);
|
||
|
if idx>-1 then
|
||
|
A.IntfIdx:=StrToInt(FIL.ValueFromIndex[idx])
|
||
|
else
|
||
|
A.IntfIdx:=ai.Index;
|
||
|
|
||
|
if A.Alias='' then begin
|
||
|
if Assigned(ConvertInterfaceIndexToLuid) and (ConvertInterfaceIndexToLuid(A.IntfIdx,@luid)=0) then
|
||
|
if ConvertInterfaceLuidToAlias(@luid,@alias,SizeOf(alias))=0 then
|
||
|
A.Alias:=alias;
|
||
|
end;
|
||
|
|
||
|
if A.Typ in [atOther, atEthernet, atTokenRing, atFDDI, atPPP, atLoopback, atATM, atIEEE80211, atTunnel, atIEEE1394, atIEEE80216_WMAN, atWWANPP, atWWANPP2] then
|
||
|
Add(A);
|
||
|
ai:=ai.Next;
|
||
|
end;
|
||
|
end;
|
||
|
finally
|
||
|
if Assigned(aiInitPtr) then
|
||
|
FreeMem(aiInitPtr);
|
||
|
end;
|
||
|
|
||
|
if Assigned(GetAdaptersAddresses) then begin
|
||
|
size:=SizeOf(IP_ADAPTER_ADDRESSES);
|
||
|
aaInitPtr:=AllocMem(size);
|
||
|
try
|
||
|
r:=GetAdaptersAddresses(AF_INET,GAA_FLAG_INCLUDE_PREFIX,nil,aaInitPtr,@size);
|
||
|
while(r=ERROR_BUFFER_OVERFLOW) do begin
|
||
|
size:=Size+SizeOf(IP_ADAPTER_ADDRESSES);
|
||
|
ReallocMem(aaInitPtr,size);
|
||
|
r:=GetAdaptersAddresses(AF_INET,GAA_FLAG_INCLUDE_PREFIX,nil,aaInitPtr,@size);
|
||
|
end;
|
||
|
aa:=aaInitPtr;
|
||
|
if(r=ERROR_SUCCESS) then begin
|
||
|
while assigned(aa) do begin
|
||
|
idx:=FindAdapter(aa.Union.IfIndex);
|
||
|
if idx>-1 then begin
|
||
|
FAdapters[idx].DNSEnabled:=aa.Flags and IP_ADAPTER_DDNS_ENABLED>0;
|
||
|
FAdapters[idx].NETBIOSEnabled:=aa.Flags and IP_ADAPTER_NETBIOS_OVER_TCPIP_ENABLED>0;
|
||
|
FAdapters[idx].IPv4Enabled:=aa.Flags and IP_ADAPTER_IPV4_ENABLED>0;
|
||
|
FAdapters[idx].IPv6Enabled:=aa.Flags and IP_ADAPTER_IPV6_ENABLED>0;
|
||
|
FAdapters[idx].DNSSuffix:=aa.DnsSuffix;
|
||
|
dns:=aa^.FirstDnsServerAddress;
|
||
|
lastdns:=nil;
|
||
|
while Assigned(dns) and (lastdns<>dns) do begin
|
||
|
lastdns:=dns;
|
||
|
Move(dns.Address.lpSockaddr^,sa4,sizeof(sa4));
|
||
|
s:=IPv4ToStr(InAddrToIPv4(sa4.sin_addr));
|
||
|
FAdapters[idx].DNSServers_v4.Add(s);
|
||
|
FDNSList4.Add(s);
|
||
|
dns:=dns.Next;
|
||
|
end;
|
||
|
FAdapters[idx].DNSSuffix:=aa.DnsSuffix;
|
||
|
end;
|
||
|
aa:=aa.Next;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
r:=GetAdaptersAddresses(AF_INET6,GAA_FLAG_INCLUDE_PREFIX,nil,aaInitPtr,@size);
|
||
|
while(r=ERROR_BUFFER_OVERFLOW) do begin
|
||
|
size:=Size+SizeOf(IP_ADAPTER_ADDRESSES);
|
||
|
ReallocMem(aaInitPtr,size);
|
||
|
r:=GetAdaptersAddresses(AF_INET6,GAA_FLAG_INCLUDE_PREFIX,nil,aaInitPtr,@size);
|
||
|
end;
|
||
|
aa:=aaInitPtr;
|
||
|
if(r=ERROR_SUCCESS) then begin
|
||
|
while assigned(aa) do begin
|
||
|
idx:=FindAdapter(aa.Union.IfIndex);
|
||
|
if idx>-1 then begin
|
||
|
fua:=aa^.FirstUnicastAddress;
|
||
|
lastfua:=nil;
|
||
|
while Assigned(fua) and (lastfua<>fua) do begin
|
||
|
lastfua:=fua;
|
||
|
Move(fua.Address.lpSockaddr^,sa6,sizeof(sa6));
|
||
|
if Assigned(InetNtop) then begin
|
||
|
ZeroMemory(@buf,sizeof(buf));
|
||
|
InetNtop(AF_INET6,@sa6.sin6_addr,@buf,sizeof(buf));
|
||
|
s:=string(buf);
|
||
|
end else
|
||
|
s:=IPv6ToStr(InAddrToIPv6(sa6.sin6_addr));
|
||
|
FAdapters[idx].IPv6Address.Add(s);
|
||
|
fua:=fua.Next;
|
||
|
end;
|
||
|
|
||
|
dns:=aa^.FirstDnsServerAddress;
|
||
|
lastdns:=nil;
|
||
|
while Assigned(dns) and (lastdns<>dns) do begin
|
||
|
lastdns:=dns;
|
||
|
Move(dns.Address.lpSockaddr^,sa6,sizeof(sa6));
|
||
|
if Assigned(InetNtop) then begin
|
||
|
ZeroMemory(@buf,sizeof(buf));
|
||
|
InetNtop(AF_INET6,@sa6.sin6_addr,@buf,sizeof(buf));
|
||
|
s:=string(buf);
|
||
|
end else
|
||
|
s:=IPv6ToStr(InAddrToIPv6(sa6.sin6_addr));
|
||
|
FAdapters[idx].DNSServers_v6.Add(s);
|
||
|
FDNSList6.Add(s);
|
||
|
dns:=dns.Next;
|
||
|
end;
|
||
|
|
||
|
gw:=aa^.FirstGatewayAddress;
|
||
|
lastgw:=nil;
|
||
|
while Assigned(gw) and (lastgw<>gw) do begin
|
||
|
lastgw:=gw;
|
||
|
Move(gw.Address.lpSockaddr^,sa6,sizeof(sa6));
|
||
|
if Assigned(InetNtop) then begin
|
||
|
ZeroMemory(@buf,sizeof(buf));
|
||
|
InetNtop(AF_INET6,@sa6.sin6_addr,@buf,sizeof(buf));
|
||
|
s:=string(buf);
|
||
|
end else
|
||
|
s:=IPv6ToStr(InAddrToIPv6(sa6.sin6_addr));
|
||
|
FAdapters[idx].Gateways_v6.Add(s);
|
||
|
gw:=gw.Next;
|
||
|
end;
|
||
|
|
||
|
wins:=aa^.FirstWinsServerAddress;
|
||
|
lastwins:=nil;
|
||
|
while Assigned(wins) and (lastwins<>wins) do begin
|
||
|
lastwins:=wins;
|
||
|
Move(wins.Address.lpSockaddr^,sa6,sizeof(sa6));
|
||
|
if Assigned(InetNtop) then begin
|
||
|
ZeroMemory(@buf,sizeof(buf));
|
||
|
InetNtop(AF_INET6,@sa6.sin6_addr,@buf,sizeof(buf));
|
||
|
s:=string(buf);
|
||
|
end else
|
||
|
s:=IPv6ToStr(InAddrToIPv6(sa6.sin6_addr));
|
||
|
FAdapters[idx].PrimaryWINS_v4.Add(s);
|
||
|
wins:=wins.Next;
|
||
|
end;
|
||
|
|
||
|
if Assigned(aa.Dhcpv6Server.lpSockaddr) then begin
|
||
|
Move(aa.Dhcpv6Server.lpSockaddr^,sa6,sizeof(sa6));
|
||
|
if Assigned(InetNtop) then begin
|
||
|
ZeroMemory(@buf,sizeof(buf));
|
||
|
InetNtop(AF_INET6,@sa6.sin6_addr,@buf,sizeof(buf));
|
||
|
s:=string(buf);
|
||
|
end else
|
||
|
s:=IPv6ToStr(InAddrToIPv6(sa6.sin6_addr));
|
||
|
FAdapters[idx].DHCPServers_v6.Add(s);
|
||
|
end;
|
||
|
end;
|
||
|
aa:=aa.Next;
|
||
|
end;
|
||
|
end;
|
||
|
finally
|
||
|
if Assigned(aaInitPtr) then
|
||
|
FreeMem(aaInitPtr);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
size:=0;
|
||
|
r:=GetIPAddrTable(nil,@size,False);
|
||
|
if r=ERROR_NO_DATA then
|
||
|
Exit;
|
||
|
GetMem(pBuf,size);
|
||
|
n:=0;
|
||
|
try
|
||
|
r:=GetIpAddrTable(PMIB_IPADDRTABLE(pBuf),@Size,False);
|
||
|
if r=NO_ERROR then begin
|
||
|
pb:=pBuf;
|
||
|
n:=PMIB_IPADDRTABLE(pb)^.dwNumEntries;
|
||
|
if n>0 then begin
|
||
|
Inc(pb,SizeOf(Cardinal));
|
||
|
SetLength(FAT,n);
|
||
|
for j:=1 to n do begin
|
||
|
IPAdrRow:=PMIB_IPADDRROW(pb)^;
|
||
|
FAT[j-1].IP:=IPv4ToStr(CardinalToIPv4(Swap32(IPAdrRow.dwAddr)));
|
||
|
FAT[j-1].Mask:=IPv4ToStr(CardinalToIPv4(Swap32(IPAdrRow.dwMask)));
|
||
|
FAT[j-1].IntfIdx:=IPAdrRow.dwIndex;
|
||
|
FAT[j-1].Typ:=[];
|
||
|
if IPAdrRow.wType and MIB_IPADDR_PRIMARY>0 then
|
||
|
Include(FAT[j-1].Typ,atPrimary);
|
||
|
if IPAdrRow.wType and MIB_IPADDR_DYNAMIC>0 then
|
||
|
Include(FAT[j-1].Typ,atDynamic);
|
||
|
if IPAdrRow.wType and MIB_IPADDR_DISCONNECTED>0 then
|
||
|
Include(FAT[j-1].Typ,atDisconnected);
|
||
|
if IPAdrRow.wType and MIB_IPADDR_DELETED>0 then
|
||
|
Include(FAT[j-1].Typ,atDeleted);
|
||
|
if IPAdrRow.wType and MIB_IPADDR_TRANSIENT>0 then
|
||
|
Include(FAT[j-1].Typ,atTransient);
|
||
|
Inc(pb,SizeOf(IPAdrRow));
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
finally
|
||
|
try FreeMem(pBuf) except end;
|
||
|
end;
|
||
|
|
||
|
Size:=0;
|
||
|
r:=GetIPNetTable(nil,@Size,False);
|
||
|
if r=ERROR_NO_DATA then
|
||
|
Exit;
|
||
|
GetMem(pBuf,Size);
|
||
|
n:=0;
|
||
|
try
|
||
|
r:=GetIpNetTable(PMIB_IPNETTABLE(pBuf),@Size,False);
|
||
|
if r=NO_ERROR then begin
|
||
|
pb:=pBuf;
|
||
|
n:=PMIB_IPNETTABLE(pb)^.dwNumEntries;
|
||
|
if n>0 then begin
|
||
|
Inc(pb,SizeOf(Cardinal));
|
||
|
SetLength(FARP,n);
|
||
|
for j:=1 to n do begin
|
||
|
IPNetRow:=PMIB_IPNETROW(pb)^;
|
||
|
FARP[j-1].IP:=IPv4ToStr(CardinalToIPv4(Swap32(IPNetRow.dwAddr)));
|
||
|
FARP[j-1].Mask:='255.255.255.0';
|
||
|
FARP[j-1].IntfIdx:=IPNetRow.dwIndex;
|
||
|
FARP[j-1].Typ:=[];
|
||
|
FARP[j-1].ARPType:=IPNetRow.dwType;
|
||
|
s:='';
|
||
|
if IPNetRow.dwPhysAddrLen>0 then begin
|
||
|
for i:=0 to IPNetRow.dwPhysAddrLen-1 do
|
||
|
s:=s+Format('%2.2x:',[IPNetRow.bPhysAddr[i]]);
|
||
|
SetLength(s,Length(s)-1);
|
||
|
end;
|
||
|
FARP[j-1].Physical:=s;
|
||
|
Inc(pb,SizeOf(IPAdrRow));
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
finally
|
||
|
try FreeMem(pBuf) except end;
|
||
|
end;
|
||
|
|
||
|
r:=GetBestInterface(inet_addr(PAnsiChar('8.8.8.8')),n);
|
||
|
if r=NO_ERROR then
|
||
|
FBII:=n
|
||
|
else
|
||
|
FBII:=FindFirstOperationalIntfIdx;
|
||
|
finally
|
||
|
FRefreshing:=False;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TNetworkConfiguration.SetAdapterImageIndex(Index: Word;
|
||
|
const Value: integer);
|
||
|
begin
|
||
|
FAdapters[Index]._ImageIndex:=Value;
|
||
|
end;
|
||
|
|
||
|
procedure TNetworkConfiguration.SetAdapterMark(Index: Word;
|
||
|
const Value: boolean);
|
||
|
begin
|
||
|
FAdapters[Index]._Mark:=Value;
|
||
|
end;
|
||
|
|
||
|
class function TNetworkConfiguration.SetDNS(AIntfIdx: Cardinal; AStatic: Boolean;
|
||
|
APreferred, AAlternate: string): Int64;
|
||
|
const
|
||
|
WbemUser='';
|
||
|
WbemPassword='';
|
||
|
WbemComputer='localhost';
|
||
|
wbemFlagForwardOnly=$00000020;
|
||
|
var
|
||
|
FSWbemLocator,
|
||
|
FWMIService,
|
||
|
FWbemObjectSet,
|
||
|
FWbemObject,
|
||
|
FOutParams,
|
||
|
vDNS: OLEVariant;
|
||
|
oEnum: IEnumVariant;
|
||
|
iValue: LongWord;
|
||
|
begin
|
||
|
FSWbemLocator:=CreateOleObject('WbemScripting.SWbemLocator');
|
||
|
FWMIService:=FSWbemLocator.ConnectServer(WbemComputer,'root\CIMV2',WbemUser,WbemPassword);
|
||
|
FWbemObjectSet:=FWMIService.ExecQuery(Format('SELECT * FROM Win32_NetworkAdapterConfiguration WHERE InterfaceIndex=%d',[AIntfIdx]),'WQL',wbemFlagForwardOnly);
|
||
|
oEnum:=IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
|
||
|
if oEnum.Next(1,FWbemObject,iValue)=0 then begin
|
||
|
if AStatic then begin
|
||
|
if Length(AAlternate)>3 then
|
||
|
vDNS:=VarArrayCreate([0,1],varVariant)
|
||
|
else
|
||
|
vDNS:=VarArrayCreate([0,0],varVariant);
|
||
|
vDNS[0]:=APreferred;
|
||
|
if Length(AAlternate)>3 then
|
||
|
vDNS[1]:=AAlternate;
|
||
|
FOutParams:=FWbemObject.SetDNSServerSearchOrder(vDNS);
|
||
|
Result:=FOutParams;
|
||
|
end else begin
|
||
|
FOutParams:=FWbemObject.SetDNSServerSearchOrder(null);
|
||
|
Result:=FOutParams;
|
||
|
end;
|
||
|
end else
|
||
|
Result:=-1;
|
||
|
end;
|
||
|
|
||
|
class function TNetworkConfiguration.SetIP(AIntfIdx: Cardinal; AStatic: Boolean; AIPv4,AMask,AGateway: string): Int64;
|
||
|
const
|
||
|
WbemUser='';
|
||
|
WbemPassword='';
|
||
|
WbemComputer='localhost';
|
||
|
wbemFlagForwardOnly=$00000020;
|
||
|
var
|
||
|
FSWbemLocator,
|
||
|
FWMIService,
|
||
|
FWbemObjectSet,
|
||
|
FWbemObject,
|
||
|
FOutParams,
|
||
|
vIpAddress,
|
||
|
vGateways,
|
||
|
vMask: OLEVariant;
|
||
|
oEnum: IEnumVariant;
|
||
|
iValue: LongWord;
|
||
|
begin
|
||
|
FSWbemLocator:=CreateOleObject('WbemScripting.SWbemLocator');
|
||
|
FWMIService:=FSWbemLocator.ConnectServer(WbemComputer,'root\CIMV2',WbemUser,WbemPassword);
|
||
|
FWbemObjectSet:=FWMIService.ExecQuery(Format('SELECT * FROM Win32_NetworkAdapterConfiguration WHERE InterfaceIndex=%d',[AIntfIdx]),'WQL',wbemFlagForwardOnly);
|
||
|
oEnum:=IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
|
||
|
if oEnum.Next(1,FWbemObject,iValue)=0 then begin
|
||
|
if AStatic then begin
|
||
|
vIpAddress:=VarArrayCreate([0,0],varVariant);
|
||
|
vIpAddress[0]:=AIPv4;
|
||
|
vMask:=VarArrayCreate([0,0],varVariant);
|
||
|
vMask[0]:=AMask;
|
||
|
FOutParams:=FWbemObject.EnableStatic(vIpAddress,vMask);
|
||
|
Result:=FOutParams;
|
||
|
vGateways:=VarArrayCreate([0,0],varVariant);
|
||
|
vGateways[0]:=AGateway;
|
||
|
FOutParams:=FWbemObject.SetGateways(vGateways);
|
||
|
if Result=0 then
|
||
|
Result:=FOutParams;
|
||
|
end else begin
|
||
|
FOutParams:=FWbemObject.EnableDHCP;
|
||
|
Result:=FOutParams;
|
||
|
end;
|
||
|
end else
|
||
|
Result:=-1;
|
||
|
end;
|
||
|
|
||
|
end.
|