synamisc.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. {==============================================================================|
  2. | Project : Ararat Synapse | 001.003.000 |
  3. |==============================================================================|
  4. | Content: misc. procedures and functions |
  5. |==============================================================================|
  6. | Copyright (c)1999-2008, Lukas Gebauer |
  7. | All rights reserved. |
  8. | |
  9. | Redistribution and use in source and binary forms, with or without |
  10. | modification, are permitted provided that the following conditions are met: |
  11. | |
  12. | Redistributions of source code must retain the above copyright notice, this |
  13. | list of conditions and the following disclaimer. |
  14. | |
  15. | Redistributions in binary form must reproduce the above copyright notice, |
  16. | this list of conditions and the following disclaimer in the documentation |
  17. | and/or other materials provided with the distribution. |
  18. | |
  19. | Neither the name of Lukas Gebauer nor the names of its contributors may |
  20. | be used to endorse or promote products derived from this software without |
  21. | specific prior written permission. |
  22. | |
  23. | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
  24. | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
  25. | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
  26. | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR |
  27. | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
  28. | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
  29. | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
  30. | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
  31. | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
  32. | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
  33. | DAMAGE. |
  34. |==============================================================================|
  35. | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
  36. | Portions created by Lukas Gebauer are Copyright (c) 2002-2008. |
  37. | All Rights Reserved. |
  38. |==============================================================================|
  39. | Contributor(s): |
  40. |==============================================================================|
  41. | History: see HISTORY.HTM from distribution package |
  42. | (Found at URL: http://www.ararat.cz/synapse/) |
  43. |==============================================================================}
  44. {:@abstract(Misc. network based utilities)}
  45. {$IFDEF FPC}
  46. {$MODE DELPHI}
  47. {$ENDIF}
  48. {$Q-}
  49. {$H+}
  50. unit synamisc;
  51. interface
  52. {$IFDEF VER125}
  53. {$DEFINE BCB}
  54. {$ENDIF}
  55. {$IFDEF BCB}
  56. {$ObjExportAll On}
  57. {$HPPEMIT '#pragma comment( lib , "wininet.lib" )'}
  58. {$ENDIF}
  59. uses
  60. synautil, blcksock, SysUtils, Classes,
  61. {$IFDEF LINUX}
  62. Libc;
  63. {$ELSE}
  64. Windows;
  65. {$ENDIF}
  66. Type
  67. {:@abstract(This record contains information about proxy setting.)}
  68. TProxySetting = record
  69. Host: string;
  70. Port: string;
  71. Bypass: string;
  72. end;
  73. {:By this function you can turn-on computer on network, if this computer
  74. supporting Wake-on-lan feature. You need MAC number (network card indentifier)
  75. of computer for turn-on. You can also assign target IP addres. If you not
  76. specify it, then is used broadcast for delivery magic wake-on packet. However
  77. broadcasts workinh only on your local network. When you need to wake-up
  78. computer on another network, you must specify any existing IP addres on same
  79. network segment as targeting computer.}
  80. procedure WakeOnLan(MAC, IP: string);
  81. {:Autodetect current DNS servers used by system. If is defined more then one DNS
  82. server, then result is comma-delimited.}
  83. function GetDNS: string;
  84. {:Autodetect InternetExplorer proxy setting for given protocol. This function
  85. working only on windows!}
  86. function GetIEProxy(protocol: string): TProxySetting;
  87. {:Return all known IP addresses on local system. Addresses are divided by comma.}
  88. function GetLocalIPs: string;
  89. implementation
  90. {==============================================================================}
  91. procedure WakeOnLan(MAC, IP: string);
  92. var
  93. sock: TUDPBlockSocket;
  94. HexMac: Ansistring;
  95. data: Ansistring;
  96. n: integer;
  97. b: Byte;
  98. begin
  99. if MAC <> '' then
  100. begin
  101. MAC := ReplaceString(MAC, '-', '');
  102. MAC := ReplaceString(MAC, ':', '');
  103. if Length(MAC) < 12 then
  104. Exit;
  105. HexMac := '';
  106. for n := 0 to 5 do
  107. begin
  108. b := StrToIntDef('$' + MAC[n * 2 + 1] + MAC[n * 2 + 2], 0);
  109. HexMac := HexMac + char(b);
  110. end;
  111. if IP = '' then
  112. IP := cBroadcast;
  113. sock := TUDPBlockSocket.Create;
  114. try
  115. sock.CreateSocket;
  116. sock.EnableBroadcast(true);
  117. sock.Connect(IP, '9');
  118. data := #$FF + #$FF + #$FF + #$FF + #$FF + #$FF;
  119. for n := 1 to 16 do
  120. data := data + HexMac;
  121. sock.SendString(data);
  122. finally
  123. sock.Free;
  124. end;
  125. end;
  126. end;
  127. {==============================================================================}
  128. {$IFNDEF LINUX}
  129. function GetDNSbyIpHlp: string;
  130. type
  131. PTIP_ADDRESS_STRING = ^TIP_ADDRESS_STRING;
  132. TIP_ADDRESS_STRING = array[0..15] of Ansichar;
  133. PTIP_ADDR_STRING = ^TIP_ADDR_STRING;
  134. TIP_ADDR_STRING = packed record
  135. Next: PTIP_ADDR_STRING;
  136. IpAddress: TIP_ADDRESS_STRING;
  137. IpMask: TIP_ADDRESS_STRING;
  138. Context: DWORD;
  139. end;
  140. PTFixedInfo = ^TFixedInfo;
  141. TFixedInfo = packed record
  142. HostName: array[1..128 + 4] of Ansichar;
  143. DomainName: array[1..128 + 4] of Ansichar;
  144. CurrentDNSServer: PTIP_ADDR_STRING;
  145. DNSServerList: TIP_ADDR_STRING;
  146. NodeType: UINT;
  147. ScopeID: array[1..256 + 4] of Ansichar;
  148. EnableRouting: UINT;
  149. EnableProxy: UINT;
  150. EnableDNS: UINT;
  151. end;
  152. const
  153. IpHlpDLL = 'IPHLPAPI.DLL';
  154. var
  155. IpHlpModule: THandle;
  156. FixedInfo: PTFixedInfo;
  157. InfoSize: Longint;
  158. PDnsServer: PTIP_ADDR_STRING;
  159. err: integer;
  160. GetNetworkParams: function(FixedInfo: PTFixedInfo; pOutPutLen: PULONG): DWORD; stdcall;
  161. begin
  162. InfoSize := 0;
  163. Result := '...';
  164. IpHlpModule := LoadLibrary(IpHlpDLL);
  165. if IpHlpModule = 0 then
  166. exit;
  167. try
  168. GetNetworkParams := GetProcAddress(IpHlpModule,PAnsiChar(AnsiString('GetNetworkParams')));
  169. if @GetNetworkParams = nil then
  170. Exit;
  171. err := GetNetworkParams(Nil, @InfoSize);
  172. if err <> ERROR_BUFFER_OVERFLOW then
  173. Exit;
  174. Result := '';
  175. GetMem (FixedInfo, InfoSize);
  176. try
  177. err := GetNetworkParams(FixedInfo, @InfoSize);
  178. if err <> ERROR_SUCCESS then
  179. exit;
  180. with FixedInfo^ do
  181. begin
  182. Result := DnsServerList.IpAddress;
  183. PDnsServer := DnsServerList.Next;
  184. while PDnsServer <> Nil do
  185. begin
  186. if Result <> '' then
  187. Result := Result + ',';
  188. Result := Result + PDnsServer^.IPAddress;
  189. PDnsServer := PDnsServer.Next;
  190. end;
  191. end;
  192. finally
  193. FreeMem(FixedInfo);
  194. end;
  195. finally
  196. FreeLibrary(IpHlpModule);
  197. end;
  198. end;
  199. function ReadReg(SubKey, Vn: PChar): string;
  200. var
  201. OpenKey: HKEY;
  202. DataType, DataSize: integer;
  203. Temp: array [0..2048] of char;
  204. begin
  205. Result := '';
  206. if RegOpenKeyEx(HKEY_LOCAL_MACHINE, SubKey, REG_OPTION_NON_VOLATILE,
  207. KEY_READ, OpenKey) = ERROR_SUCCESS then
  208. begin
  209. DataType := REG_SZ;
  210. DataSize := SizeOf(Temp);
  211. if RegQueryValueEx(OpenKey, Vn, nil, @DataType, @Temp, @DataSize) = ERROR_SUCCESS then
  212. SetString(Result, Temp, DataSize div SizeOf(Char) - 1);
  213. RegCloseKey(OpenKey);
  214. end;
  215. end ;
  216. {$ENDIF}
  217. function GetDNS: string;
  218. {$IFDEF LINUX}
  219. var
  220. l: TStringList;
  221. n: integer;
  222. begin
  223. Result := '';
  224. l := TStringList.Create;
  225. try
  226. l.LoadFromFile('/etc/resolv.conf');
  227. for n := 0 to l.Count - 1 do
  228. if Pos('NAMESERVER', uppercase(l[n])) = 1 then
  229. begin
  230. if Result <> '' then
  231. Result := Result + ',';
  232. Result := Result + SeparateRight(l[n], ' ');
  233. end;
  234. finally
  235. l.Free;
  236. end;
  237. end;
  238. {$ELSE}
  239. const
  240. NTdyn = 'System\CurrentControlSet\Services\Tcpip\Parameters\Temporary';
  241. NTfix = 'System\CurrentControlSet\Services\Tcpip\Parameters';
  242. W9xfix = 'System\CurrentControlSet\Services\MSTCP';
  243. begin
  244. Result := GetDNSbyIpHlp;
  245. if Result = '...' then
  246. begin
  247. if Win32Platform = VER_PLATFORM_WIN32_NT then
  248. begin
  249. Result := ReadReg(NTdyn, 'NameServer');
  250. if result = '' then
  251. Result := ReadReg(NTfix, 'NameServer');
  252. if result = '' then
  253. Result := ReadReg(NTfix, 'DhcpNameServer');
  254. end
  255. else
  256. Result := ReadReg(W9xfix, 'NameServer');
  257. Result := ReplaceString(trim(Result), ' ', ',');
  258. end;
  259. end;
  260. {$ENDIF}
  261. {==============================================================================}
  262. function GetIEProxy(protocol: string): TProxySetting;
  263. {$IFDEF LINUX}
  264. begin
  265. Result.Host := '';
  266. Result.Port := '';
  267. Result.Bypass := '';
  268. end;
  269. {$ELSE}
  270. type
  271. PInternetProxyInfo = ^TInternetProxyInfo;
  272. TInternetProxyInfo = packed record
  273. dwAccessType: DWORD;
  274. lpszProxy: LPCSTR;
  275. lpszProxyBypass: LPCSTR;
  276. end;
  277. const
  278. INTERNET_OPTION_PROXY = 38;
  279. INTERNET_OPEN_TYPE_PROXY = 3;
  280. WininetDLL = 'WININET.DLL';
  281. var
  282. WininetModule: THandle;
  283. ProxyInfo: PInternetProxyInfo;
  284. Err: Boolean;
  285. Len: DWORD;
  286. Proxy: string;
  287. DefProxy: string;
  288. ProxyList: TStringList;
  289. n: integer;
  290. InternetQueryOption: function (hInet: Pointer; dwOption: DWORD;
  291. lpBuffer: Pointer; var lpdwBufferLength: DWORD): BOOL; stdcall;
  292. begin
  293. Result.Host := '';
  294. Result.Port := '';
  295. Result.Bypass := '';
  296. WininetModule := LoadLibrary(WininetDLL);
  297. if WininetModule = 0 then
  298. exit;
  299. try
  300. InternetQueryOption := GetProcAddress(WininetModule,PAnsiChar(AnsiString('InternetQueryOptionA')));
  301. if @InternetQueryOption = nil then
  302. Exit;
  303. if protocol = '' then
  304. protocol := 'http';
  305. Len := 4096;
  306. GetMem(ProxyInfo, Len);
  307. ProxyList := TStringList.Create;
  308. try
  309. Err := InternetQueryOption(nil, INTERNET_OPTION_PROXY, ProxyInfo, Len);
  310. if Err then
  311. if ProxyInfo^.dwAccessType = INTERNET_OPEN_TYPE_PROXY then
  312. begin
  313. ProxyList.CommaText := ReplaceString(ProxyInfo^.lpszProxy, ' ', ',');
  314. Proxy := '';
  315. DefProxy := '';
  316. for n := 0 to ProxyList.Count -1 do
  317. begin
  318. if Pos(lowercase(protocol) + '=', lowercase(ProxyList[n])) = 1 then
  319. begin
  320. Proxy := SeparateRight(ProxyList[n], '=');
  321. break;
  322. end;
  323. if Pos('=', ProxyList[n]) < 1 then
  324. DefProxy := ProxyList[n];
  325. end;
  326. if Proxy = '' then
  327. Proxy := DefProxy;
  328. if Proxy <> '' then
  329. begin
  330. Result.Host := Trim(SeparateLeft(Proxy, ':'));
  331. Result.Port := Trim(SeparateRight(Proxy, ':'));
  332. end;
  333. Result.Bypass := ReplaceString(ProxyInfo^.lpszProxyBypass, ' ', ',');
  334. end;
  335. finally
  336. ProxyList.Free;
  337. FreeMem(ProxyInfo);
  338. end;
  339. finally
  340. FreeLibrary(WininetModule);
  341. end;
  342. end;
  343. {$ENDIF}
  344. {==============================================================================}
  345. function GetLocalIPs: string;
  346. var
  347. TcpSock: TTCPBlockSocket;
  348. ipList: TStringList;
  349. begin
  350. Result := '';
  351. ipList := TStringList.Create;
  352. try
  353. TcpSock := TTCPBlockSocket.create;
  354. try
  355. TcpSock.ResolveNameToIP(TcpSock.LocalName, ipList);
  356. Result := ipList.CommaText;
  357. finally
  358. TcpSock.Free;
  359. end;
  360. finally
  361. ipList.Free;
  362. end;
  363. end;
  364. {==============================================================================}
  365. end.