/* * Copyright 2007 ThoughtWorks, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ // Hudsuckr Windows Proxy Configuration Tool // "You know, for kids!" #define _WIN32_WINNT 0x0500 // Change this to the appropriate value to target other versions of Windows. #include <stdio.h> #include <tchar.h> #include <windows.h> #include <wininet.h> #include <ras.h> #pragma comment( lib, "wininet" ) #pragma comment( lib, "rasapi32" ) Options used in INTERNET_PER_CONN_OPTON struct //#define INTERNET_PER_CONN_FLAGS 1 //#define INTERNET_PER_CONN_PROXY_SERVER 2 //#define INTERNET_PER_CONN_PROXY_BYPASS 3 //#define INTERNET_PER_CONN_AUTOCONFIG_URL 4 //#define INTERNET_PER_CONN_AUTODISCOVERY_FLAGS 5 //etc. PER_CONN_FLAGS //#define PROXY_TYPE_DIRECT 0x00000001 // direct to net //#define PROXY_TYPE_PROXY 0x00000002 // via named proxy //#define PROXY_TYPE_AUTO_PROXY_URL 0x00000004 // autoproxy URL //#define PROXY_TYPE_AUTO_DETECT 0x00000008 // use autoproxy detection // Figure out which Dial-Up or VPN connection is active; in a normal LAN connection, this should // return NULL LPTSTR FindActiveConnection() { DWORD dwCb = sizeof(RASCONN); DWORD dwErr = ERROR_SUCCESS; DWORD dwRetries = 5; DWORD dwConnections = 0; RASCONN* lpRasConn = NULL; RASCONNSTATUS rasconnstatus; rasconnstatus.dwSize = sizeof(RASCONNSTATUS); // // Loop through in case the information from RAS changes between calls. // while (dwRetries--) { // // If the memory is allocated, free it. // if (NULL != lpRasConn) { HeapFree(GetProcessHeap(), 0, lpRasConn); lpRasConn = NULL; } // // Allocate the size needed for the RAS structure. // lpRasConn = (RASCONN*)HeapAlloc(GetProcessHeap(), 0, dwCb); if (NULL == lpRasConn) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; } // // Set the structure size for version checking purposes. // lpRasConn->dwSize = sizeof(RASCONN); // // Call the RAS API then exit the loop if we are successful or an unknown // error occurs. // dwErr = RasEnumConnections( lpRasConn, &dwCb, &dwConnections); if (ERROR_INSUFFICIENT_BUFFER != dwErr) { break; } } // // In the success case, print the names of the connections. // if (ERROR_SUCCESS == dwErr) { DWORD i; for (i = 0; i < dwConnections; i++) { RasGetConnectStatus(lpRasConn[i].hrasconn, &rasconnstatus); if (rasconnstatus.rasconnstate == RASCS_Connected) { return lpRasConn[i].szEntryName; } } } return NULL; // Couldn't find an active dial-up/VPN connection; return NULL } int QueryOptions(LPTSTR szActiveConnection) { _tprintf(L"ACTIVE_CONNECTION=%s/n", (szActiveConnection == NULL ? L"": szActiveConnection)); const int optionCount = 5; INTERNET_PER_CONN_OPTION_LIST List; INTERNET_PER_CONN_OPTION Option[optionCount]; unsigned long nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST); Option[0].dwOption = 1; for (int i = 1; i < optionCount; i++) { Option[i].dwOption = i; } List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST); List.pszConnection = szActiveConnection; List.dwOptionCount = optionCount; List.dwOptionError = 0; List.pOptions = Option; if(!InternetQueryOption(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, &nSize)) { DWORD lastError = GetLastError(); _tprintf(L"InternetQueryOption failed! (%d)/n", lastError); return lastError; } _tprintf(L"PROXY_TYPE_DIRECT="); if((Option[INTERNET_PER_CONN_FLAGS].Value.dwValue & PROXY_TYPE_DIRECT) == PROXY_TYPE_DIRECT) { _tprintf(L"true/n"); } else { _tprintf(L"false/n"); } _tprintf(L"PROXY_TYPE_PROXY="); if((Option[INTERNET_PER_CONN_FLAGS].Value.dwValue & PROXY_TYPE_PROXY) == PROXY_TYPE_PROXY) { _tprintf(L"true/n"); } else { _tprintf(L"false/n"); } _tprintf(L"PROXY_TYPE_AUTO_PROXY_URL="); if((Option[INTERNET_PER_CONN_FLAGS].Value.dwValue & PROXY_TYPE_AUTO_PROXY_URL) == PROXY_TYPE_AUTO_PROXY_URL) { _tprintf(L"true/n"); } else { _tprintf(L"false/n"); } _tprintf(L"PROXY_TYPE_AUTO_DETECT="); if((Option[INTERNET_PER_CONN_FLAGS].Value.dwValue & PROXY_TYPE_AUTO_DETECT) == PROXY_TYPE_AUTO_DETECT) { _tprintf(L"true/n"); } else { _tprintf(L"false/n"); } _tprintf(L"INTERNET_PER_CONN_PROXY_SERVER="); if(Option[INTERNET_PER_CONN_PROXY_SERVER].Value.pszValue != NULL) { _tprintf(L"%s/n", Option[INTERNET_PER_CONN_PROXY_SERVER].Value.pszValue); } else { _tprintf(L"/n"); } _tprintf(L"INTERNET_PER_CONN_PROXY_BYPASS="); if(Option[INTERNET_PER_CONN_PROXY_BYPASS].Value.pszValue != NULL) { _tprintf(L"%s/n", Option[INTERNET_PER_CONN_PROXY_BYPASS].Value.pszValue); } else { _tprintf(L"/n"); } _tprintf(L"INTERNET_PER_CONN_AUTOCONFIG_URL="); if(Option[INTERNET_PER_CONN_AUTOCONFIG_URL].Value.pszValue != NULL) { _tprintf(L"%s/n", Option[INTERNET_PER_CONN_AUTOCONFIG_URL].Value.pszValue); } else { _tprintf(L"/n"); } return 0; } int _tmain(int argc, _TCHAR* argv[]) { if (argc < 2) return QueryOptions(FindActiveConnection()); if (argc != 9) { printf("Hudsuckr Windows Proxy Configuration Tool: /"You know, for kids!/"/n/n" "Windows manages Internet proxy connection information in the registry;/n" "each Internet /"connection/" can have its own separate proxy/n" "configuration. These settings correspond to settings in the /"Internet/n" "Options/" Control Panel, under the /"Connections/" tab./n/n" "Run /"hudsuckr/" without arguments to print out the current proxy/n" "configuration details. We print out the name of the current active/n" "connection, the four connection flags (DIRECT, PROXY, AUTO_PROXY_URL,/n" "AUTO_DETECT), and three strings: PROXY_SERVER, PROXY_BYPASS, and/n" "AUTOCONFIG_URL. The seven settings are described in MS documentation/n" "available here: http://msdn2.microsoft.com/en-us/library/aa385145.aspx/n/n" "Run /"hudsuckr/" with exactly eight arguments to set the proxy/n" "configuration, like this:/n" " hudsuckr /"/" true true true true /"localhost:4444/" /"<local>/" /"file://c:/proxy.pac/"/n/n" "Specify the name of the connection first (or use the LAN settings by/n" "specifying the blank string /"/"), then set the four flags using /"true/"/n" "and /"false/", then the proxy server (with a colon to specify the port),/n" "the list of servers to bypass delimited by semi-colons (with /"<local>/"/n" "as a special string that bypasses local addresses), and finally the/n" "URL to a proxy PAC autoconfiguration file. Use /"/" to leave string/n" "settings blank/empty./n/n" "If you're still confused about the flags, look at the proxy settings/n" "in the /"Internet Options/" Control Panel. See how you can check those/n" "checkboxes independently of one another? The flags correspond to those/n" "checkboxes. If AUTO_DETECT is true, IE will try to use WPAD; if/n" "successful, WPAD will override the specified AUTOCONFIG_URL. If an/n" "AUTOCONFIG_URL is detected (by AUTO_DETECT) or specified directly/n" "(AUTO_PROXY_URL is enabled), IE will use the autoconfig script as a/n" "proxy PAC file. If no AUTOCONFIG_URL was specified or detected, IE/n" "will attempt to use the server specified in PROXY_SERVER if the PROXY/n" "flag is enabled; it will bypass the proxy for the list of servers/n" "specified in PROXY_BYPASS. Finally, if PROXY, AUTO_DETECT and/n" "AUTO_PROXY_URL are all set to false, IE will attempt to contact the/n" "web server directly. Note that the DIRECT flag always appears to be/n" "true, even if the PROXY flag is true; we recommend you leave it that/n" "way, too." ); return -1; } BOOL bDirect, bProxy, bAutoProxyUrl, bAutoDetect; LPTSTR szActiveConnection, szProxyServer, szProxyBypass, szAutoConfigUrl; int i = 1; szActiveConnection = argv[i++]; if (_tcslen(szActiveConnection) == 0) { szActiveConnection = NULL; } bDirect = (_tcsicmp(argv[i++], L"true") == 0); bProxy = (_tcsicmp(argv[i++], L"true") == 0); bAutoProxyUrl = (_tcsicmp(argv[i++], L"true") == 0); bAutoDetect = (_tcsicmp(argv[i++], L"true") == 0); DWORD dwConnFlags; dwConnFlags = bDirect + (bProxy << 1) + (bAutoProxyUrl << 2) + (bAutoDetect << 3); szProxyServer = argv[i++]; if (_tcslen(szProxyServer) == 0) { szProxyServer = NULL; } szProxyBypass = argv[i++]; if (_tcslen(szProxyBypass) == 0) { szProxyBypass = NULL; } szAutoConfigUrl = argv[i++]; if (_tcslen(szAutoConfigUrl) == 0) { szAutoConfigUrl = NULL; } const int optionCount = 4; INTERNET_PER_CONN_OPTION_LIST List; INTERNET_PER_CONN_OPTION Option[optionCount]; unsigned long nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST); i = 0; Option[i].dwOption = INTERNET_PER_CONN_FLAGS; Option[i++].Value.dwValue = dwConnFlags; Option[i].dwOption = INTERNET_PER_CONN_PROXY_SERVER; Option[i++].Value.pszValue = szProxyServer; Option[i].dwOption = INTERNET_PER_CONN_PROXY_BYPASS; Option[i++].Value.pszValue = szProxyBypass; Option[i].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL; Option[i++].Value.pszValue = szAutoConfigUrl; List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST); List.pszConnection = szActiveConnection; List.dwOptionCount = optionCount; List.dwOptionError = 0; List.pOptions = Option; if(!InternetSetOption(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, nSize)) { DWORD lastError = GetLastError(); printf("InternetSetOption failed! (%d)/n", lastError); return lastError; } if(!InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0)) { DWORD lastError = GetLastError(); printf("InternetSetOption failed! (%d)/n", lastError); return lastError; } return QueryOptions(szActiveConnection); }
Hudsuckr Windows Proxy Configuration Tool
最新推荐文章于 2020-09-21 14:54:37 发布