Subversion Repositories userdetect2

Rev

Rev 71 | Rev 92 | 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
73 daniel-mar 19
  iphlp, 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;
28
  addr: string;
29
  addrStr: IP_ADDR_STRING;
30
  BufLen: Cardinal;
31
begin
32
  BufLen := SizeOf(IP_ADAPTER_INFO);
70 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
37
    Result := GetAdaptersInfo(pAdapterInfo, @BufLen);
70 daniel-mar 38
    if Result <> ERROR_SUCCESS then Exit;
68 daniel-mar 39
    while pAdapterInfo <> nil do
40
    begin
41
      addrStr := pAdapterInfo^.IpAddressList;
42
      repeat
43
        addr := addrStr.IpAddress.S;
44
        if (addr <> '') and (outsl.IndexOf(addr) = -1) then
45
          outsl.Add(addr);
46
        if addrStr.Next = nil then break;
47
        AddrStr := addrStr.Next^;
48
      until false;
49
      pAdapterInfo := pAdapterInfo^.next;
50
    end;
51
  finally
52
    Freemem(pAdapterInfo);
53
  end;
54
end;
55
 
56
function GetDHCPIPAddressList(outsl: TStrings): DWORD;
57
var
58
  pAdapterInfo: PIP_ADAPTER_INFO;
59
  addr: string;
60
  addrStr: IP_ADDR_STRING;
61
  BufLen: Cardinal;
62
begin
63
  BufLen := SizeOf(IP_ADAPTER_INFO);
70 daniel-mar 64
  Result := GetAdaptersInfo(nil, @BufLen);
71 daniel-mar 65
  if Result <> ERROR_BUFFER_OVERFLOW then Exit;
68 daniel-mar 66
  pAdapterInfo := AllocMem(BufLen);
67
  try
68
    Result := GetAdaptersInfo(pAdapterInfo, @BufLen);
70 daniel-mar 69
    if Result <> ERROR_SUCCESS then Exit;
68 daniel-mar 70
    while pAdapterInfo <> nil do
71
    begin
72
      addrStr := pAdapterInfo^.DhcpServer;
73
      repeat
74
        addr := addrStr.IpAddress.S;
75
        if (addr <> '') and (outsl.IndexOf(addr) = -1) then
76
          outsl.Add(addr);
77
        if addrStr.Next = nil then break;
78
        AddrStr := addrStr.Next^;
79
      until false;
80
      pAdapterInfo := pAdapterInfo^.next;
81
    end;
82
  finally
83
    Freemem(pAdapterInfo);
84
  end;
85
end;
86
 
87
function GetGatewayIPAddressList(outsl: TStrings): DWORD;
88
var
89
  pAdapterInfo: PIP_ADAPTER_INFO;
90
  addr: string;
91
  addrStr: IP_ADDR_STRING;
92
  BufLen: Cardinal;
93
begin
94
  BufLen := SizeOf(IP_ADAPTER_INFO);
70 daniel-mar 95
  Result := GetAdaptersInfo(nil, @BufLen);
71 daniel-mar 96
  if Result <> ERROR_BUFFER_OVERFLOW then Exit;
68 daniel-mar 97
  pAdapterInfo := AllocMem(BufLen);
98
  try
99
    Result := GetAdaptersInfo(pAdapterInfo, @BufLen);
70 daniel-mar 100
    if Result <> ERROR_SUCCESS then Exit;
68 daniel-mar 101
    while pAdapterInfo <> nil do
102
    begin
103
      addrStr := pAdapterInfo^.GatewayList;
104
      repeat
105
        addr := addrStr.IpAddress.S;
106
        if (addr <> '') and (outsl.IndexOf(addr) = -1) then
107
          outsl.Add(addr);
108
        if addrStr.Next = nil then break;
109
        AddrStr := addrStr.Next^;
110
      until false;
111
      pAdapterInfo := pAdapterInfo^.next;
112
    end;
113
  finally
114
    Freemem(pAdapterInfo);
115
  end;
116
end;
117
 
118
function GetMACAddress(const IPAddress: string; var outAddress: string): DWORD;
119
// http://stackoverflow.com/questions/4550672/delphi-get-mac-of-router
120
var
121
  MacAddr    : Array[0..5] of Byte;
122
  DestIP     : ULONG;
123
  PhyAddrLen : ULONG;
124
  WSAData    : TWSAData;
125
  j: integer;
126
begin
127
  outAddress := '';
128
  WSAStartup($0101, WSAData);
129
  try
130
    ZeroMemory(@MacAddr, SizeOf(MacAddr));
131
    DestIP     := inet_addr(PAnsiChar(IPAddress));
132
    PhyAddrLen := SizeOf(MacAddr); // TODO: more ?
133
    Result     := SendArp(DestIP, 0, @MacAddr, @PhyAddrLen);
134
    if Result = S_OK then
135
    begin
136
      outAddress := '';
137
      for j := 0 to PhyAddrLen-1 do
138
      begin
139
        outAddress := outAddress + format('%.2x', [MacAddr[j]]);
140
      end;
141
      outAddress := FormatMAC(outAddress);
142
    end;
143
  finally
144
    WSACleanup;
145
  end;
146
end;
147
 
148
function GetLocalMACAddressList(outSL: TStrings): DWORD;
149
const
150
  _MAX_ROWS_ = 100;
151
type
152
  _IfTable = Record
153
    nRows: LongInt;
154
    ifRow: Array[1.._MAX_ROWS_] of MIB_IFROW;
155
  end;
156
var
157
  pIfTable: ^_IfTable;
158
  TableSize: LongInt;
159
  tmp: String;
160
  i, j: Integer;
161
begin
162
  pIfTable := nil;
163
  try
164
    // First: just get the buffer size.
165
    // TableSize returns the size needed.
166
    TableSize := 0; // Set to zero so the GetIfTabel function
167
    // won't try to fill the buffer yet,
168
    // but only return the actual size it needs.
169
    GetIfTable(pIfTable, TableSize, 1);
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);
180
    Result := GetIfTable(pIfTable, TableSize, 1);
181
    if Result <> NO_ERROR then Exit;
182
 
183
    // Read the ETHERNET addresses.
184
    for i := 1 to pIfTable^.nRows do
185
    begin
186
      //if pIfTable^.ifRow[i].dwType=MIB_IF_TYPE_ETHERNET then
187
      begin
188
        tmp := '';
189
        for j := 0 to pIfTable^.ifRow[i].dwPhysAddrLen-1 do
190
        begin
191
          tmp := tmp + format('%.2x', [pIfTable^.ifRow[i].bPhysAddr[j]]);
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.