Subversion Repositories userdetect2

Rev

Rev 73 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
68 daniel-mar 1
unit NetworkUtils;
2
 
3
interface
4
 
5
uses
6
  Windows, SysUtils, Classes;
7
 
8
function GetLocalIPAddressList(outsl: TStrings): DWORD;
9
function GetLocalMACAddressList(outSL: TStrings): DWORD;
10
function GetDHCPIPAddressList(outsl: TStrings): DWORD;
11
function GetGatewayIPAddressList(outsl: TStrings): DWORD;
12
function GetMACAddress(const IPAddress: string; var outAddress: string): DWORD;
13
function FormatMAC(s: string): string;
73 daniel-mar 14
function GetDomainName(var outDomainName: WideString): boolean;
68 daniel-mar 15
 
16
implementation
17
 
18
uses
92 daniel-mar 19
  iphlpapi, IpTypes, Iprtrmib, WinSock, Registry;
68 daniel-mar 20
 
21
// TODO: Replace GetAdaptersInfo()? A comment at MSDN states that there might be problems with IPv6
22
//           "GetAdaptersInfo returns ERROR_NO_DATA if there are only IPv6 interfaces
23
//            configured on system. In that case GetAdapterAddresses has to be used!"
24
 
25
function GetLocalIPAddressList(outsl: TStrings): DWORD;
26
var
27
  pAdapterInfo: PIP_ADAPTER_INFO;
92 daniel-mar 28
  addr: AnsiString;
68 daniel-mar 29
  addrStr: IP_ADDR_STRING;
30
  BufLen: Cardinal;
31
begin
32
  BufLen := SizeOf(IP_ADAPTER_INFO);
92 daniel-mar 33
  Result := GetAdaptersInfo(nil, BufLen);
71 daniel-mar 34
  if Result <> ERROR_BUFFER_OVERFLOW then Exit;
68 daniel-mar 35
  pAdapterInfo := AllocMem(BufLen);
36
  try
92 daniel-mar 37
    ZeroMemory(pAdapterInfo, BufLen);
38
    Result := GetAdaptersInfo(pAdapterInfo, BufLen);
70 daniel-mar 39
    if Result <> ERROR_SUCCESS then Exit;
68 daniel-mar 40
    while pAdapterInfo <> nil do
41
    begin
42
      addrStr := pAdapterInfo^.IpAddressList;
43
      repeat
44
        addr := addrStr.IpAddress.S;
45
        if (addr <> '') and (outsl.IndexOf(addr) = -1) then
46
          outsl.Add(addr);
47
        if addrStr.Next = nil then break;
48
        AddrStr := addrStr.Next^;
49
      until false;
50
      pAdapterInfo := pAdapterInfo^.next;
51
    end;
52
  finally
53
    Freemem(pAdapterInfo);
54
  end;
55
end;
56
 
57
function GetDHCPIPAddressList(outsl: TStrings): DWORD;
58
var
59
  pAdapterInfo: PIP_ADAPTER_INFO;
92 daniel-mar 60
  addr: AnsiString;
68 daniel-mar 61
  addrStr: IP_ADDR_STRING;
62
  BufLen: Cardinal;
63
begin
64
  BufLen := SizeOf(IP_ADAPTER_INFO);
92 daniel-mar 65
  Result := GetAdaptersInfo(nil, BufLen);
71 daniel-mar 66
  if Result <> ERROR_BUFFER_OVERFLOW then Exit;
68 daniel-mar 67
  pAdapterInfo := AllocMem(BufLen);
68
  try
92 daniel-mar 69
    ZeroMemory(pAdapterInfo, BufLen);
70
    Result := GetAdaptersInfo(pAdapterInfo, BufLen);
70 daniel-mar 71
    if Result <> ERROR_SUCCESS then Exit;
68 daniel-mar 72
    while pAdapterInfo <> nil do
73
    begin
74
      addrStr := pAdapterInfo^.DhcpServer;
75
      repeat
76
        addr := addrStr.IpAddress.S;
77
        if (addr <> '') and (outsl.IndexOf(addr) = -1) then
78
          outsl.Add(addr);
79
        if addrStr.Next = nil then break;
80
        AddrStr := addrStr.Next^;
81
      until false;
82
      pAdapterInfo := pAdapterInfo^.next;
83
    end;
84
  finally
85
    Freemem(pAdapterInfo);
86
  end;
87
end;
88
 
89
function GetGatewayIPAddressList(outsl: TStrings): DWORD;
90
var
91
  pAdapterInfo: PIP_ADAPTER_INFO;
92 daniel-mar 92
  addr: AnsiString;
68 daniel-mar 93
  addrStr: IP_ADDR_STRING;
94
  BufLen: Cardinal;
95
begin
96
  BufLen := SizeOf(IP_ADAPTER_INFO);
92 daniel-mar 97
  Result := GetAdaptersInfo(nil, BufLen);
71 daniel-mar 98
  if Result <> ERROR_BUFFER_OVERFLOW then Exit;
68 daniel-mar 99
  pAdapterInfo := AllocMem(BufLen);
100
  try
92 daniel-mar 101
    ZeroMemory(pAdapterInfo, BufLen);
102
    Result := GetAdaptersInfo(pAdapterInfo, BufLen);
70 daniel-mar 103
    if Result <> ERROR_SUCCESS then Exit;
68 daniel-mar 104
    while pAdapterInfo <> nil do
105
    begin
106
      addrStr := pAdapterInfo^.GatewayList;
107
      repeat
108
        addr := addrStr.IpAddress.S;
109
        if (addr <> '') and (outsl.IndexOf(addr) = -1) then
110
          outsl.Add(addr);
111
        if addrStr.Next = nil then break;
112
        AddrStr := addrStr.Next^;
113
      until false;
114
      pAdapterInfo := pAdapterInfo^.next;
115
    end;
116
  finally
117
    Freemem(pAdapterInfo);
118
  end;
119
end;
120
 
121
function GetMACAddress(const IPAddress: string; var outAddress: string): DWORD;
122
// http://stackoverflow.com/questions/4550672/delphi-get-mac-of-router
123
var
124
  MacAddr    : Array[0..5] of Byte;
125
  DestIP     : ULONG;
126
  PhyAddrLen : ULONG;
127
  WSAData    : TWSAData;
128
  j: integer;
129
begin
130
  outAddress := '';
131
  WSAStartup($0101, WSAData);
132
  try
133
    ZeroMemory(@MacAddr, SizeOf(MacAddr));
134
    DestIP     := inet_addr(PAnsiChar(IPAddress));
135
    PhyAddrLen := SizeOf(MacAddr); // TODO: more ?
92 daniel-mar 136
    Result     := SendArp(DestIP, 0, @MacAddr, PhyAddrLen);
68 daniel-mar 137
    if Result = S_OK then
138
    begin
139
      outAddress := '';
140
      for j := 0 to PhyAddrLen-1 do
141
      begin
142
        outAddress := outAddress + format('%.2x', [MacAddr[j]]);
143
      end;
144
      outAddress := FormatMAC(outAddress);
145
    end;
146
  finally
147
    WSACleanup;
148
  end;
149
end;
150
 
151
function GetLocalMACAddressList(outSL: TStrings): DWORD;
152
var
92 daniel-mar 153
  pIfTable: PMIB_IFTABLE;
154
  TableSize: Cardinal;
68 daniel-mar 155
  tmp: String;
156
  i, j: Integer;
157
begin
158
  pIfTable := nil;
159
  try
160
    // First: just get the buffer size.
161
    // TableSize returns the size needed.
92 daniel-mar 162
    TableSize := 0; // Set to zero so the GetIfTable function won't try to fill the buffer yet,
163
                    // but only return the actual size it needs.
164
    GetIfTable(pIfTable, TableSize, true);
68 daniel-mar 165
    if (TableSize < SizeOf(MIB_IFROW)+SizeOf(LongInt)) then
166
    begin
167
      Result := ERROR_NO_DATA;
168
      Exit; // less than 1 table entry?!
169
    end;
170
 
171
    // Second:
172
    // allocate memory for the buffer and retrieve the
173
    // entire table.
174
    GetMem(pIfTable, TableSize);
92 daniel-mar 175
    Result := GetIfTable(pIfTable, TableSize, true);
68 daniel-mar 176
    if Result <> NO_ERROR then Exit;
177
 
178
    // Read the ETHERNET addresses.
92 daniel-mar 179
    for i := 1 to pIfTable^.dwNumEntries do
68 daniel-mar 180
    begin
92 daniel-mar 181
      //if pIfTable^.table[i].dwType = MIB_IF_TYPE_ETHERNET then
68 daniel-mar 182
      begin
183
        tmp := '';
92 daniel-mar 184
        for j := 0 to pIfTable^.table[i].dwPhysAddrLen-1 do
68 daniel-mar 185
        begin
92 daniel-mar 186
          tmp := tmp + format('%.2x', [pIfTable^.table[i].bPhysAddr[j]]);
68 daniel-mar 187
        end;
188
        tmp := FormatMAC(tmp);
189
        if (tmp <> '') and (outSL.IndexOf(tmp) = -1) then
190
          outSL.Add(tmp);
191
      end;
192
    end;
193
  finally
194
    if Assigned(pIfTable) then FreeMem(pIfTable, TableSize);
195
  end;
196
end;
197
 
198
function FormatMAC(s: string): string;
199
var
200
  m: integer;
201
begin
202
  result := '';
203
  m := 1;
204
  s := UpperCase(s);
205
  repeat
206
    if m > 1 then result := result + '-';
207
    result := result + Copy(s, m, 2);
208
    inc(m, 2);
209
  until m > Length(s);
210
end;
211
 
73 daniel-mar 212
(*
213
type
214
  WKSTA_INFO_100   = Record
215
      wki100_platform_id  : DWORD;
216
      wki100_computername : LPWSTR;
217
      wki100_langroup     : LPWSTR;
218
      wki100_ver_major    : DWORD;
219
      wki100_ver_minor    : DWORD;
220
  End;
221
 
222
   LPWKSTA_INFO_100 = ^WKSTA_INFO_100;
223
 
224
function GetNetParam(AParam: integer): string;
225
Var
226
  PBuf  : LPWKSTA_INFO_100;
227
  Res   : LongInt;
228
begin
229
  result := '';
230
  Res := NetWkstaGetInfo(nil, 100, @PBuf);
231
  If Res = NERR_Success Then
232
    begin
233
      case AParam of
234
       0:   Result := string(PBuf^.wki100_computername);
235
       1:   Result := string(PBuf^.wki100_langroup);
236
      end;
237
    end;
238
end;
239
 
240
function GetTheComputerName: string;
241
begin
242
  Result := GetNetParam(0);
243
end;
244
 
245
function GetTheDomainName: string;
246
begin
247
  Result := GetNetParam(1);
248
end;
249
 
250
*)
251
 
252
function GetDomainName(var outDomainName: WideString): boolean;
253
var
254
  reg: TRegistry;
255
begin
256
  outDomainName := '';
257
  reg := TRegistry.Create;
258
  try
259
    reg.RootKey := HKEY_LOCAL_MACHINE;
260
    result := reg.OpenKeyReadOnly('\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters');
261
    if result then
262
    begin
263
      outDomainName := reg.ReadString('Domain');
264
      reg.CloseKey;
265
    end;
266
  finally
267
    reg.Free;
268
  end;
269
end;
270
 
68 daniel-mar 271
end.