Rev 71 | Rev 92 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 71 | Rev 73 | ||
---|---|---|---|
1 | unit NetworkUtils; |
1 | unit NetworkUtils; |
2 | 2 | ||
3 | interface |
3 | interface |
4 | 4 | ||
5 | uses |
5 | uses |
6 | Windows, SysUtils, Classes; |
6 | Windows, SysUtils, Classes; |
7 | 7 | ||
8 | function GetLocalIPAddressList(outsl: TStrings): DWORD; |
8 | function GetLocalIPAddressList(outsl: TStrings): DWORD; |
9 | function GetLocalMACAddressList(outSL: TStrings): DWORD; |
9 | function GetLocalMACAddressList(outSL: TStrings): DWORD; |
10 | function GetDHCPIPAddressList(outsl: TStrings): DWORD; |
10 | function GetDHCPIPAddressList(outsl: TStrings): DWORD; |
11 | function GetGatewayIPAddressList(outsl: TStrings): DWORD; |
11 | function GetGatewayIPAddressList(outsl: TStrings): DWORD; |
12 | function GetMACAddress(const IPAddress: string; var outAddress: string): DWORD; |
12 | function GetMACAddress(const IPAddress: string; var outAddress: string): DWORD; |
13 | function FormatMAC(s: string): string; |
13 | function FormatMAC(s: string): string; |
- | 14 | function GetDomainName(var outDomainName: WideString): boolean; |
|
14 | 15 | ||
15 | implementation |
16 | implementation |
16 | 17 | ||
17 | uses |
18 | uses |
18 | iphlp, WinSock; |
19 | iphlp, WinSock, Registry; |
19 | 20 | ||
20 | // TODO: Replace GetAdaptersInfo()? A comment at MSDN states that there might be problems with IPv6 |
21 | // TODO: Replace GetAdaptersInfo()? A comment at MSDN states that there might be problems with IPv6 |
21 | // "GetAdaptersInfo returns ERROR_NO_DATA if there are only IPv6 interfaces |
22 | // "GetAdaptersInfo returns ERROR_NO_DATA if there are only IPv6 interfaces |
22 | // configured on system. In that case GetAdapterAddresses has to be used!" |
23 | // configured on system. In that case GetAdapterAddresses has to be used!" |
23 | 24 | ||
24 | function GetLocalIPAddressList(outsl: TStrings): DWORD; |
25 | function GetLocalIPAddressList(outsl: TStrings): DWORD; |
25 | var |
26 | var |
26 | pAdapterInfo: PIP_ADAPTER_INFO; |
27 | pAdapterInfo: PIP_ADAPTER_INFO; |
27 | addr: string; |
28 | addr: string; |
28 | addrStr: IP_ADDR_STRING; |
29 | addrStr: IP_ADDR_STRING; |
29 | BufLen: Cardinal; |
30 | BufLen: Cardinal; |
30 | begin |
31 | begin |
31 | BufLen := SizeOf(IP_ADAPTER_INFO); |
32 | BufLen := SizeOf(IP_ADAPTER_INFO); |
32 | Result := GetAdaptersInfo(nil, @BufLen); |
33 | Result := GetAdaptersInfo(nil, @BufLen); |
33 | if Result <> ERROR_BUFFER_OVERFLOW then Exit; |
34 | if Result <> ERROR_BUFFER_OVERFLOW then Exit; |
34 | pAdapterInfo := AllocMem(BufLen); |
35 | pAdapterInfo := AllocMem(BufLen); |
35 | try |
36 | try |
36 | Result := GetAdaptersInfo(pAdapterInfo, @BufLen); |
37 | Result := GetAdaptersInfo(pAdapterInfo, @BufLen); |
37 | if Result <> ERROR_SUCCESS then Exit; |
38 | if Result <> ERROR_SUCCESS then Exit; |
38 | while pAdapterInfo <> nil do |
39 | while pAdapterInfo <> nil do |
39 | begin |
40 | begin |
40 | addrStr := pAdapterInfo^.IpAddressList; |
41 | addrStr := pAdapterInfo^.IpAddressList; |
41 | repeat |
42 | repeat |
42 | addr := addrStr.IpAddress.S; |
43 | addr := addrStr.IpAddress.S; |
43 | if (addr <> '') and (outsl.IndexOf(addr) = -1) then |
44 | if (addr <> '') and (outsl.IndexOf(addr) = -1) then |
44 | outsl.Add(addr); |
45 | outsl.Add(addr); |
45 | if addrStr.Next = nil then break; |
46 | if addrStr.Next = nil then break; |
46 | AddrStr := addrStr.Next^; |
47 | AddrStr := addrStr.Next^; |
47 | until false; |
48 | until false; |
48 | pAdapterInfo := pAdapterInfo^.next; |
49 | pAdapterInfo := pAdapterInfo^.next; |
49 | end; |
50 | end; |
50 | finally |
51 | finally |
51 | Freemem(pAdapterInfo); |
52 | Freemem(pAdapterInfo); |
52 | end; |
53 | end; |
53 | end; |
54 | end; |
54 | 55 | ||
55 | function GetDHCPIPAddressList(outsl: TStrings): DWORD; |
56 | function GetDHCPIPAddressList(outsl: TStrings): DWORD; |
56 | var |
57 | var |
57 | pAdapterInfo: PIP_ADAPTER_INFO; |
58 | pAdapterInfo: PIP_ADAPTER_INFO; |
58 | addr: string; |
59 | addr: string; |
59 | addrStr: IP_ADDR_STRING; |
60 | addrStr: IP_ADDR_STRING; |
60 | BufLen: Cardinal; |
61 | BufLen: Cardinal; |
61 | begin |
62 | begin |
62 | BufLen := SizeOf(IP_ADAPTER_INFO); |
63 | BufLen := SizeOf(IP_ADAPTER_INFO); |
63 | Result := GetAdaptersInfo(nil, @BufLen); |
64 | Result := GetAdaptersInfo(nil, @BufLen); |
64 | if Result <> ERROR_BUFFER_OVERFLOW then Exit; |
65 | if Result <> ERROR_BUFFER_OVERFLOW then Exit; |
65 | pAdapterInfo := AllocMem(BufLen); |
66 | pAdapterInfo := AllocMem(BufLen); |
66 | try |
67 | try |
67 | Result := GetAdaptersInfo(pAdapterInfo, @BufLen); |
68 | Result := GetAdaptersInfo(pAdapterInfo, @BufLen); |
68 | if Result <> ERROR_SUCCESS then Exit; |
69 | if Result <> ERROR_SUCCESS then Exit; |
69 | while pAdapterInfo <> nil do |
70 | while pAdapterInfo <> nil do |
70 | begin |
71 | begin |
71 | addrStr := pAdapterInfo^.DhcpServer; |
72 | addrStr := pAdapterInfo^.DhcpServer; |
72 | repeat |
73 | repeat |
73 | addr := addrStr.IpAddress.S; |
74 | addr := addrStr.IpAddress.S; |
74 | if (addr <> '') and (outsl.IndexOf(addr) = -1) then |
75 | if (addr <> '') and (outsl.IndexOf(addr) = -1) then |
75 | outsl.Add(addr); |
76 | outsl.Add(addr); |
76 | if addrStr.Next = nil then break; |
77 | if addrStr.Next = nil then break; |
77 | AddrStr := addrStr.Next^; |
78 | AddrStr := addrStr.Next^; |
78 | until false; |
79 | until false; |
79 | pAdapterInfo := pAdapterInfo^.next; |
80 | pAdapterInfo := pAdapterInfo^.next; |
80 | end; |
81 | end; |
81 | finally |
82 | finally |
82 | Freemem(pAdapterInfo); |
83 | Freemem(pAdapterInfo); |
83 | end; |
84 | end; |
84 | end; |
85 | end; |
85 | 86 | ||
86 | function GetGatewayIPAddressList(outsl: TStrings): DWORD; |
87 | function GetGatewayIPAddressList(outsl: TStrings): DWORD; |
87 | var |
88 | var |
88 | pAdapterInfo: PIP_ADAPTER_INFO; |
89 | pAdapterInfo: PIP_ADAPTER_INFO; |
89 | addr: string; |
90 | addr: string; |
90 | addrStr: IP_ADDR_STRING; |
91 | addrStr: IP_ADDR_STRING; |
91 | BufLen: Cardinal; |
92 | BufLen: Cardinal; |
92 | begin |
93 | begin |
93 | BufLen := SizeOf(IP_ADAPTER_INFO); |
94 | BufLen := SizeOf(IP_ADAPTER_INFO); |
94 | Result := GetAdaptersInfo(nil, @BufLen); |
95 | Result := GetAdaptersInfo(nil, @BufLen); |
95 | if Result <> ERROR_BUFFER_OVERFLOW then Exit; |
96 | if Result <> ERROR_BUFFER_OVERFLOW then Exit; |
96 | pAdapterInfo := AllocMem(BufLen); |
97 | pAdapterInfo := AllocMem(BufLen); |
97 | try |
98 | try |
98 | Result := GetAdaptersInfo(pAdapterInfo, @BufLen); |
99 | Result := GetAdaptersInfo(pAdapterInfo, @BufLen); |
99 | if Result <> ERROR_SUCCESS then Exit; |
100 | if Result <> ERROR_SUCCESS then Exit; |
100 | while pAdapterInfo <> nil do |
101 | while pAdapterInfo <> nil do |
101 | begin |
102 | begin |
102 | addrStr := pAdapterInfo^.GatewayList; |
103 | addrStr := pAdapterInfo^.GatewayList; |
103 | repeat |
104 | repeat |
104 | addr := addrStr.IpAddress.S; |
105 | addr := addrStr.IpAddress.S; |
105 | if (addr <> '') and (outsl.IndexOf(addr) = -1) then |
106 | if (addr <> '') and (outsl.IndexOf(addr) = -1) then |
106 | outsl.Add(addr); |
107 | outsl.Add(addr); |
107 | if addrStr.Next = nil then break; |
108 | if addrStr.Next = nil then break; |
108 | AddrStr := addrStr.Next^; |
109 | AddrStr := addrStr.Next^; |
109 | until false; |
110 | until false; |
110 | pAdapterInfo := pAdapterInfo^.next; |
111 | pAdapterInfo := pAdapterInfo^.next; |
111 | end; |
112 | end; |
112 | finally |
113 | finally |
113 | Freemem(pAdapterInfo); |
114 | Freemem(pAdapterInfo); |
114 | end; |
115 | end; |
115 | end; |
116 | end; |
116 | 117 | ||
117 | function GetMACAddress(const IPAddress: string; var outAddress: string): DWORD; |
118 | function GetMACAddress(const IPAddress: string; var outAddress: string): DWORD; |
118 | // http://stackoverflow.com/questions/4550672/delphi-get-mac-of-router |
119 | // http://stackoverflow.com/questions/4550672/delphi-get-mac-of-router |
119 | var |
120 | var |
120 | MacAddr : Array[0..5] of Byte; |
121 | MacAddr : Array[0..5] of Byte; |
121 | DestIP : ULONG; |
122 | DestIP : ULONG; |
122 | PhyAddrLen : ULONG; |
123 | PhyAddrLen : ULONG; |
123 | WSAData : TWSAData; |
124 | WSAData : TWSAData; |
124 | j: integer; |
125 | j: integer; |
125 | begin |
126 | begin |
126 | outAddress := ''; |
127 | outAddress := ''; |
127 | WSAStartup($0101, WSAData); |
128 | WSAStartup($0101, WSAData); |
128 | try |
129 | try |
129 | ZeroMemory(@MacAddr, SizeOf(MacAddr)); |
130 | ZeroMemory(@MacAddr, SizeOf(MacAddr)); |
130 | DestIP := inet_addr(PAnsiChar(IPAddress)); |
131 | DestIP := inet_addr(PAnsiChar(IPAddress)); |
131 | PhyAddrLen := SizeOf(MacAddr); // TODO: more ? |
132 | PhyAddrLen := SizeOf(MacAddr); // TODO: more ? |
132 | Result := SendArp(DestIP, 0, @MacAddr, @PhyAddrLen); |
133 | Result := SendArp(DestIP, 0, @MacAddr, @PhyAddrLen); |
133 | if Result = S_OK then |
134 | if Result = S_OK then |
134 | begin |
135 | begin |
135 | outAddress := ''; |
136 | outAddress := ''; |
136 | for j := 0 to PhyAddrLen-1 do |
137 | for j := 0 to PhyAddrLen-1 do |
137 | begin |
138 | begin |
138 | outAddress := outAddress + format('%.2x', [MacAddr[j]]); |
139 | outAddress := outAddress + format('%.2x', [MacAddr[j]]); |
139 | end; |
140 | end; |
140 | outAddress := FormatMAC(outAddress); |
141 | outAddress := FormatMAC(outAddress); |
141 | end; |
142 | end; |
142 | finally |
143 | finally |
143 | WSACleanup; |
144 | WSACleanup; |
144 | end; |
145 | end; |
145 | end; |
146 | end; |
146 | 147 | ||
147 | function GetLocalMACAddressList(outSL: TStrings): DWORD; |
148 | function GetLocalMACAddressList(outSL: TStrings): DWORD; |
148 | const |
149 | const |
149 | _MAX_ROWS_ = 100; |
150 | _MAX_ROWS_ = 100; |
150 | type |
151 | type |
151 | _IfTable = Record |
152 | _IfTable = Record |
152 | nRows: LongInt; |
153 | nRows: LongInt; |
153 | ifRow: Array[1.._MAX_ROWS_] of MIB_IFROW; |
154 | ifRow: Array[1.._MAX_ROWS_] of MIB_IFROW; |
154 | end; |
155 | end; |
155 | var |
156 | var |
156 | pIfTable: ^_IfTable; |
157 | pIfTable: ^_IfTable; |
157 | TableSize: LongInt; |
158 | TableSize: LongInt; |
158 | tmp: String; |
159 | tmp: String; |
159 | i, j: Integer; |
160 | i, j: Integer; |
160 | begin |
161 | begin |
161 | pIfTable := nil; |
162 | pIfTable := nil; |
162 | try |
163 | try |
163 | // First: just get the buffer size. |
164 | // First: just get the buffer size. |
164 | // TableSize returns the size needed. |
165 | // TableSize returns the size needed. |
165 | TableSize := 0; // Set to zero so the GetIfTabel function |
166 | TableSize := 0; // Set to zero so the GetIfTabel function |
166 | // won't try to fill the buffer yet, |
167 | // won't try to fill the buffer yet, |
167 | // but only return the actual size it needs. |
168 | // but only return the actual size it needs. |
168 | GetIfTable(pIfTable, TableSize, 1); |
169 | GetIfTable(pIfTable, TableSize, 1); |
169 | if (TableSize < SizeOf(MIB_IFROW)+SizeOf(LongInt)) then |
170 | if (TableSize < SizeOf(MIB_IFROW)+SizeOf(LongInt)) then |
170 | begin |
171 | begin |
171 | Result := ERROR_NO_DATA; |
172 | Result := ERROR_NO_DATA; |
172 | Exit; // less than 1 table entry?! |
173 | Exit; // less than 1 table entry?! |
173 | end; |
174 | end; |
174 | 175 | ||
175 | // Second: |
176 | // Second: |
176 | // allocate memory for the buffer and retrieve the |
177 | // allocate memory for the buffer and retrieve the |
177 | // entire table. |
178 | // entire table. |
178 | GetMem(pIfTable, TableSize); |
179 | GetMem(pIfTable, TableSize); |
179 | Result := GetIfTable(pIfTable, TableSize, 1); |
180 | Result := GetIfTable(pIfTable, TableSize, 1); |
180 | if Result <> NO_ERROR then Exit; |
181 | if Result <> NO_ERROR then Exit; |
181 | 182 | ||
182 | // Read the ETHERNET addresses. |
183 | // Read the ETHERNET addresses. |
183 | for i := 1 to pIfTable^.nRows do |
184 | for i := 1 to pIfTable^.nRows do |
184 | begin |
185 | begin |
185 | //if pIfTable^.ifRow[i].dwType=MIB_IF_TYPE_ETHERNET then |
186 | //if pIfTable^.ifRow[i].dwType=MIB_IF_TYPE_ETHERNET then |
186 | begin |
187 | begin |
187 | tmp := ''; |
188 | tmp := ''; |
188 | for j := 0 to pIfTable^.ifRow[i].dwPhysAddrLen-1 do |
189 | for j := 0 to pIfTable^.ifRow[i].dwPhysAddrLen-1 do |
189 | begin |
190 | begin |
190 | tmp := tmp + format('%.2x', [pIfTable^.ifRow[i].bPhysAddr[j]]); |
191 | tmp := tmp + format('%.2x', [pIfTable^.ifRow[i].bPhysAddr[j]]); |
191 | end; |
192 | end; |
192 | tmp := FormatMAC(tmp); |
193 | tmp := FormatMAC(tmp); |
193 | if (tmp <> '') and (outSL.IndexOf(tmp) = -1) then |
194 | if (tmp <> '') and (outSL.IndexOf(tmp) = -1) then |
194 | outSL.Add(tmp); |
195 | outSL.Add(tmp); |
195 | end; |
196 | end; |
196 | end; |
197 | end; |
197 | finally |
198 | finally |
198 | if Assigned(pIfTable) then FreeMem(pIfTable, TableSize); |
199 | if Assigned(pIfTable) then FreeMem(pIfTable, TableSize); |
199 | end; |
200 | end; |
200 | end; |
201 | end; |
201 | 202 | ||
202 | function FormatMAC(s: string): string; |
203 | function FormatMAC(s: string): string; |
203 | var |
204 | var |
204 | m: integer; |
205 | m: integer; |
205 | begin |
206 | begin |
206 | result := ''; |
207 | result := ''; |
207 | m := 1; |
208 | m := 1; |
208 | s := UpperCase(s); |
209 | s := UpperCase(s); |
209 | repeat |
210 | repeat |
210 | if m > 1 then result := result + '-'; |
211 | if m > 1 then result := result + '-'; |
211 | result := result + Copy(s, m, 2); |
212 | result := result + Copy(s, m, 2); |
212 | inc(m, 2); |
213 | inc(m, 2); |
213 | until m > Length(s); |
214 | until m > Length(s); |
214 | end; |
215 | end; |
- | 216 | ||
- | 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; |
|
215 | 275 | ||
216 | end. |
276 | end. |
217 | 277 |