寫C++程序繞過IE的限制:“某些設置由系統管理員進行管理”

公司的電腦,其IE代理都是由“系統管理員”進行統一設置的:Auto Config URL。

打開我的IE10的設置,可以看到如下圖樣:


我修改了註冊表,卻發現其實它並未真正生效。

我平時應用的很多軟件,因爲自帶設置代理的功能,所以使用並未受影響,通過用cntlm代理,能幹很多事情。但是,iTunes這個軟件不一樣。它只能使用系統設置的代理。我爲了能使用iTunes聽那些高質量的Podcast節目,今天在網上找了一些代碼,終於成功修改了系統代理,繞過了公司的限制。下面是代碼的內容:

// ProxyConnect.cpp : Change system proxy settings programmatically.

#include "stdafx.h"
#include <Windows.h>
#include <WinInet.h>

BOOL QueryConnectionOptions(LPTSTR conn_name)
{
	INTERNET_VERSION_INFO Version;
	DWORD nSize = sizeof(INTERNET_VERSION_INFO);
	InternetQueryOption(NULL, INTERNET_OPTION_VERSION, &Version, &nSize);
	printf("[Wininet.dll Version] %d.%d\n", Version.dwMajorVersion, Version.dwMinorVersion);	

	INTERNET_PER_CONN_OPTION Option[5];							// === The most common useful settings ===
	Option[0].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL;		//1. URL to the automatic configuration script
	Option[1].dwOption = INTERNET_PER_CONN_AUTODISCOVERY_FLAGS;	//2. automatic discovery settings (flags: always_detect | use_cached_one | no_cache ...)
	Option[2].dwOption = INTERNET_PER_CONN_FLAGS;				//3. connection type (flags: direct | proxy | auto_proxy_url | auto_detect)
	Option[3].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;		//4. URLs that do not use the proxy server
	Option[4].dwOption = INTERNET_PER_CONN_PROXY_SERVER;		//5. proxy servers

	INTERNET_PER_CONN_OPTION_LIST List;		// the list of options for a particular Internet connection
	List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
	List.pszConnection = conn_name;			// the name of the RAS connection; NULL indicates the default or LAN connection, to set or query options on
	List.dwOptionCount = sizeof(Option)/sizeof(INTERNET_PER_CONN_OPTION);
	List.dwOptionError = 0;
	List.pOptions = Option;

	nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
	if(!InternetQueryOption(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, &nSize))
	{
		printf("InternetQueryOption failed! (%d)\n", GetLastError());
		return FALSE;
	}

	if(Option[0].Value.pszValue != NULL)
	{
		printf("[Auto Config URL] %s\n", Option[0].Value.pszValue);
		//! default: http://proxy.xxxxxxxx.org/proxy.pac
		GlobalFree(Option[0].Value.pszValue);
	}

	if(Option[1].Value.dwValue != 0)
	{
		printf("[Auto Discovery Settings] %x\n", Option[1].Value.pszValue);
		//! default: ZERO
	}

	if(Option[2].Value.dwValue != 0)
	{
		printf("[Connection Type] 0x%x\n", Option[2].Value.pszValue);
		//! default: 5 ( PROXY_TYPE_AUTO_PROXY_URL | PROXY_TYPE_DIRECT )

		if((Option[2].Value.dwValue & PROXY_TYPE_AUTO_PROXY_URL))
			printf(" => [PROXY_TYPE] AUTO_PROXY_URL\n");
		if((Option[2].Value.dwValue & PROXY_TYPE_AUTO_DETECT))
			printf(" => [PROXY_TYPE] AUTO_DETECT\n");
		if((Option[2].Value.dwValue & PROXY_TYPE_DIRECT))
			printf(" => [PROXY_TYPE] DIRECT\n");
		if((Option[2].Value.dwValue & PROXY_TYPE_PROXY))
			printf(" => [PROXY_TYPE] PROXY \n");
	}

	if(Option[3].Value.pszValue != NULL)
	{
		printf("[Bypass URLs] %s\n", Option[3].Value.pszValue);
		//! default: NULL
		GlobalFree(Option[3].Value.pszValue);
	}

	if(Option[4].Value.pszValue != NULL)
	{
		printf("[Proxy Servers] %s\n", Option[4].Value.pszValue);
		//! default: NULL
		GlobalFree(Option[4].Value.pszValue);
	}

	return TRUE;
}

BOOL SetConnectionOptions(LPTSTR conn_name, LPTSTR proxy_full_addr)
{
	//conn_name: active connection name.
	//proxy_full_addr : eg "210.78.22.87:8000"
	INTERNET_PER_CONN_OPTION_LIST list;
	list.dwSize = sizeof(list);
	list.pszConnection = (LPSTR) conn_name;
	list.dwOptionCount = 3;
	list.pOptions = new INTERNET_PER_CONN_OPTION[list.dwOptionCount];
	if(NULL == list.pOptions)
	{
		OutputDebugString("failed to allocat memory in SetConnectionOptions()");
		return FALSE;
	}
	// Set flags.
	list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
	list.pOptions[0].Value.dwValue = PROXY_TYPE_PROXY;	// PROXY_TYPE_DIRECT | PROXY_TYPE_PROXY

	// Set proxy name.
	list.pOptions[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
	list.pOptions[1].Value.pszValue = proxy_full_addr;//"http://proxy:80"

	// Set proxy override.
	list.pOptions[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
	list.pOptions[2].Value.pszValue = _T("local");

	// Set the options on the connection. Use NULL to make system-wide affection
	BOOL bReturn = InternetSetOption(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, sizeof(list));
	if(!bReturn)
	{
		printf("InternetSetOption failed! (%d)\n", GetLastError());
	}

	delete [] list.pOptions;

	printf("\n(Modified Options)\n");
	QueryConnectionOptions(conn_name);
	printf("\n");

	InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
	InternetSetOption(NULL, INTERNET_OPTION_REFRESH , NULL, 0);
	return bReturn;
}

BOOL RestoreDefaultSettings(LPTSTR conn_name)
{
	INTERNET_PER_CONN_OPTION_LIST list;
	list.dwSize = sizeof(list);
	list.pszConnection = conn_name;
	list.dwOptionCount = 5;
	list.pOptions = new INTERNET_PER_CONN_OPTION[list.dwOptionCount];
	if(NULL == list.pOptions)
	{
		OutputDebugString("failed to allocat memory in RestoreDefaultSettings()");
		return FALSE;
	}

	//! 1. Auto Config URL
	list.pOptions[0].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL;
	list.pOptions[0].Value.pszValue = _T("http://proxy.xxxxxxxx.org/proxy.pac");
	//! 2. Auto Discovery Settings
	list.pOptions[1].dwOption = INTERNET_PER_CONN_AUTODISCOVERY_FLAGS;
	list.pOptions[1].Value.dwValue = 0;
	//! 3. Connection Type
	list.pOptions[2].dwOption = INTERNET_PER_CONN_FLAGS;
	list.pOptions[2].Value.dwValue = (PROXY_TYPE_AUTO_PROXY_URL | PROXY_TYPE_DIRECT);
	//! 4. Bypass URLs
	list.pOptions[3].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
	list.pOptions[3].Value.pszValue = NULL;
	//! 5. Proxy Servers
	list.pOptions[4].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
	list.pOptions[4].Value.pszValue = NULL;

	// Set the options on the connection. Use NULL to make system-wide affection
	BOOL bReturn = InternetSetOption(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, sizeof(list));
	if(!bReturn)
	{
		printf("InternetSetOption failed! (%d)\n", GetLastError());
	}

	delete [] list.pOptions;

	printf("\n(Modified Options)\n");
	QueryConnectionOptions(conn_name);
	printf("\n");

	InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
	InternetSetOption(NULL, INTERNET_OPTION_REFRESH , NULL, 0);
	return bReturn;
}

int _tmain(int argc, _TCHAR* argv[])
{
    enum Operation
    {
        OP_USE_LOCAL_PROXY    = 0, // use my local CNTLM proxy
        OP_RESTORE_DEFAULT    = 1, // use system default
    } operation = OP_USE_LOCAL_PROXY;

    if (argc > 1)
    {
        if (stricmp(argv[1], _T("-disable"))==0)
            operation = OP_RESTORE_DEFAULT;
        else if (stricmp(argv[1], _T("-enable"))==0)
            operation = OP_USE_LOCAL_PROXY;
    }

    QueryConnectionOptions(NULL);    // NULL, "LAN"
    if (operation == OP_USE_LOCAL_PROXY)
    {
        SetConnectionOptions(NULL, _T("127.0.0.1:5865"));
    }
    else
    {
        RestoreDefaultSettings(NULL);
    }
    return 0;
}

使用時,使用-enable / -disable即可控制代理的開關。注意:一定要牢記默認設置,因爲很多軟件的使用都依賴它。我發現flash控件就只能通過系統默認的代理下載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章