Subversion Repositories userdetect2

Rev

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