SysProxy.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. #include "stdafx.h"
  2. #include "SysProxy.h"
  3. #include <WinInet.h>
  4. #include <assert.h>
  5. #pragma comment( lib,"wininet.lib")
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /** @brief 设置系统代理 (IE代理)
  12. *
  13. * @param lpszProxyServer 代理服务器地址, 为NULL表示不设置
  14. * @param lpszPacUrl pac地址,为NULL表示不设置
  15. * @param lpszByPass 设置By pass( 跳过代理服务器的列表 ), 为NULL的时候不设置
  16. * @param lpszPac pac地址,只有在bIsPacMode=TRUE时才有效
  17. *
  18. * @note 如果指定了lpszByPass, bLocalAddrNotUseProxy将被忽略
  19. */
  20. BOOL SetSystemProxy(
  21. LPCTSTR lpszProxyServer,
  22. LPCTSTR lpszPacUrl,
  23. LPCTSTR lpszByPass /*= NULL */,
  24. BOOL bLocalAddrNotUseProxy /* = TRUE */)
  25. {
  26. // To include server for FTP, HTTPS, and so on, use the string
  27. // (ftp=http://<ProxyServerName>:80; https=https://<ProxyServerName>:80)
  28. INTERNET_PER_CONN_OPTION_LIST List;
  29. INTERNET_PER_CONN_OPTION Option[5]; // 最多5个
  30. unsigned long nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
  31. int nPos = 0;
  32. //PrintfW( LEVEL_INFO, _T("[SetSystemProxy]: Proxy Server: %s, PacUrl: %s") , lpszProxyServer?lpszProxyServer:_T("NULL"),lpszPacUrl?lpszPacUrl:_T("NULL"));
  33. // proxy server
  34. if (lpszProxyServer)
  35. {
  36. Option[nPos].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
  37. Option[nPos].Value.pszValue = (LPTSTR)lpszProxyServer;
  38. nPos++;
  39. }
  40. if (lpszPacUrl)
  41. {
  42. Option[nPos].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL;
  43. Option[nPos].Value.pszValue = (LPTSTR)lpszPacUrl;
  44. nPos++;
  45. }
  46. // 指定连接类型
  47. // Sets or retrieves the connection type. The Value member will contain one or more of the following values:
  48. Option[nPos].dwOption = INTERNET_PER_CONN_FLAGS;
  49. Option[nPos].Value.dwValue = PROXY_TYPE_DIRECT;
  50. if (lpszProxyServer)
  51. Option[nPos].Value.dwValue |= PROXY_TYPE_PROXY;
  52. if (lpszPacUrl)
  53. Option[nPos].Value.dwValue |= PROXY_TYPE_AUTO_PROXY_URL;
  54. nPos++;
  55. // 指定不通过代理服务器的地址
  56. // Sets or retrieves a string containing the URLs that do not use the proxy server.
  57. Option[nPos].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
  58. if (lpszByPass != NULL)
  59. {
  60. Option[nPos].Value.pszValue = (LPTSTR)lpszByPass;
  61. }
  62. else
  63. {
  64. if (bLocalAddrNotUseProxy)
  65. // local;<local> 这个值是查注册表得知的. IE中设置了"对于本地地址不使用代理服务器"后就是这样的
  66. Option[nPos].Value.pszValue = _T("local;<local>");
  67. else
  68. Option[nPos].Value.pszValue = _T("local");
  69. }
  70. nPos++;
  71. List.dwSize = nSize;
  72. List.pszConnection = NULL;
  73. List.dwOptionCount = nPos;
  74. List.dwOptionError = 0;
  75. List.pOptions = Option;
  76. if (!InternetSetOption(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, nSize))
  77. {
  78. //PrintfW( LEVEL_ERROR, _T("[SetSystemProxy]: Set internet options failed, Code: %d") , GetLastError() );
  79. return FALSE;
  80. }
  81. // To refresh the global proxy settings, you must call InternetSetOption with the INTERNET_OPTION_REFRESH option flag.
  82. InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
  83. InternetSetOption(NULL, INTERNET_OPTION_REFRESH, NULL, NULL);
  84. //The connection settings for other instances of Internet Explorer.
  85. // PrintfW( LEVEL_INFO, _T("[SetSystemProxy]: Set internet options done") );
  86. return TRUE;
  87. }
  88. /** @brief 是否设置了系统代理
  89. */
  90. BOOL IsSetSystemProxy()
  91. {
  92. TCHAR szPacUrl[1024] = { 0 };
  93. TCHAR szProxy[1024] = { 0 };
  94. TCHAR szByPass[1024] = { 0 };
  95. DWORD flags = 0;
  96. BOOL bUseAutoDetect;
  97. BOOL bUseAutoConfigUrl;
  98. BOOL bUseProxyServer;
  99. if (GetSystemProxyInfo(
  100. bUseAutoDetect,
  101. bUseAutoConfigUrl,
  102. szPacUrl,
  103. 1024,
  104. bUseProxyServer,
  105. szProxy,
  106. 1024,
  107. szByPass,
  108. 1024) && (szProxy[0] != 0 || szPacUrl[0] != 0))
  109. return TRUE;
  110. return FALSE;
  111. }
  112. /** @brief 获取IE的代理设置,( 系统代理)
  113. *
  114. * @param bUseAutoDetect[out] 自动检测设置属性
  115. * @param bUseAutoConfigUrl[out] Buffer使用自动配置脚本属性
  116. * @param lpAutoConfigUrl[out] 自动配置脚本URL地址
  117. * @param nAutoConfigUrlLe[out] 自动配置脚本URL Buffer长度
  118. * @param bUseProxyServer[out] 使用代理服务器地址
  119. * @param lpProxyServer[out] 代理服务器地址
  120. * @param nProxyServerLen[out] 代理服务器地址BUFFER 长度
  121. * @param lpByPass[out] By pass字符串
  122. * @param nByPassLen[out] By pass字符串BUFFER长度
  123. * @return
  124. * TRUE 成功, 返回值在以上参数中
  125. * FALSE 失败.
  126. *
  127. * https://msdn.microsoft.com/en-us/library/aa385145.aspx
  128. */
  129. BOOL GetSystemProxyInfo(
  130. BOOL &bUseAutoDetect, // 自动检测设置属性
  131. BOOL &bUseAutoConfigUrl, // 使用自动配置脚本属性
  132. LPTSTR lpAutoConfigUrl, // 自动配置脚本URL地址
  133. int nAutoConfigUrlLen, // 自动配置脚本URL Buffer长度
  134. BOOL &bUseProxyServer, // 使用代理服务器地址
  135. LPTSTR lpProxyServer, // 代理服务器地址
  136. int nProxyServerLen, // 代理服务器地址BUFFER 长度
  137. LPTSTR lpByPass, // By pass字符串
  138. int nByPassLen // By pass字符串BUFFER长度
  139. )
  140. {
  141. assert(lpAutoConfigUrl != NULL);
  142. assert(nAutoConfigUrlLen > 0);
  143. assert(lpProxyServer != NULL);
  144. assert(nProxyServerLen > 0);
  145. assert(lpByPass != NULL);
  146. assert(nByPassLen > 0);
  147. const int optionCount = 5;
  148. INTERNET_PER_CONN_OPTION_LIST List;
  149. INTERNET_PER_CONN_OPTION Option[optionCount];
  150. unsigned long nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
  151. Option[0].dwOption = INTERNET_PER_CONN_FLAGS;
  152. Option[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
  153. Option[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
  154. Option[3].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL;
  155. Option[4].dwOption = INTERNET_PER_CONN_AUTODISCOVERY_FLAGS;
  156. //Option[0].dwOption = 1;
  157. //for (int i = 1; i < optionCount; i++) {
  158. // Option[i].dwOption = i;
  159. //}
  160. List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
  161. List.pszConnection = NULL;
  162. List.dwOptionCount = optionCount;
  163. List.dwOptionError = 0;
  164. List.pOptions = Option;
  165. if (!InternetQueryOption(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, &nSize)) {
  166. return FALSE;
  167. }
  168. // proxy server
  169. bUseProxyServer = FALSE;
  170. if ((Option[0].Value.dwValue & PROXY_TYPE_PROXY) == PROXY_TYPE_PROXY
  171. && Option[1].Value.pszValue != NULL
  172. )
  173. {
  174. bUseProxyServer = TRUE;
  175. _tcsncpy_s(lpProxyServer, nProxyServerLen, Option[1].Value.pszValue, nProxyServerLen - 1);
  176. }
  177. // autoconfig url
  178. bUseAutoConfigUrl = FALSE;
  179. if ((Option[0].Value.dwValue & PROXY_TYPE_AUTO_PROXY_URL) == PROXY_TYPE_AUTO_PROXY_URL
  180. && Option[3].Value.pszValue != NULL
  181. )
  182. {
  183. bUseAutoConfigUrl = TRUE;
  184. _tcsncpy_s(lpAutoConfigUrl, nAutoConfigUrlLen, Option[3].Value.pszValue, nAutoConfigUrlLen - 1);
  185. }
  186. // auto detect
  187. bUseAutoDetect = FALSE;
  188. if ((Option[0].Value.dwValue & PROXY_TYPE_AUTO_DETECT) == PROXY_TYPE_AUTO_DETECT)
  189. {
  190. bUseAutoDetect = TRUE;
  191. }
  192. if (Option[2].Value.pszValue != NULL)
  193. {
  194. _tcsncpy_s(lpByPass, nByPassLen, Option[2].Value.pszValue, nByPassLen - 1);
  195. }
  196. return TRUE;
  197. }
  198. /** @brief 禁用系统代理
  199. */
  200. BOOL DisableSystemProxy()
  201. {
  202. INTERNET_PER_CONN_OPTION_LIST List;
  203. INTERNET_PER_CONN_OPTION Option;
  204. unsigned long nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
  205. //PrintfW( LEVEL_INFO, _T("[DisableSystemProxy]: ...") );
  206. // Set flags.
  207. Option.dwOption = INTERNET_PER_CONN_FLAGS;
  208. Option.Value.dwValue = PROXY_TYPE_DIRECT;
  209. // Fill out list struct.
  210. List.dwSize = nSize;
  211. // NULL == LAN, otherwise connectoid name.
  212. List.pszConnection = NULL;
  213. // Set three options.
  214. List.dwOptionCount = 1;
  215. List.pOptions = &Option;
  216. // Set the options on the connection.
  217. if (!InternetSetOption(NULL,
  218. INTERNET_OPTION_PER_CONNECTION_OPTION, &List, nSize))
  219. {
  220. //PrintfW( LEVEL_ERROR, _T("[DisableSystemProxy]: Set internet options failed, Code: %d") ,GetLastError() );
  221. return FALSE;
  222. }
  223. InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
  224. InternetSetOption(NULL, INTERNET_OPTION_REFRESH, NULL, 0);
  225. //PrintfW( LEVEL_INFO, _T("[DisableSystemProxy]: Set internet options done."));
  226. return TRUE;
  227. }