1. 程式人生 > >ActiveX控制元件localhost可以呼叫,內外網IP不可以的解決辦法

ActiveX控制元件localhost可以呼叫,內外網IP不可以的解決辦法

開發ActiveX控制元件過程中遇到這樣的問題:

本機上開發完成後,用TstCon測試介面沒問題。js寫靜態頁面測試呼叫沒問題。但是給到web端開發,他們使用內網IP或者外網地址時,會報錯。如圖:

開始以為是IE本地設定的問題,把對ActiveX限制的都改為允許,但是試了之後還是不行。後來聯想到是否是因為本地除錯IE用的Intranet策略,而以IP方式訪問IE採用的是Internet策略。所以果斷去設定Internet選項,如圖,。

點開自定義級別,

把上圖中『對未標記為可安全執行指令碼的ActiveX控制元件初始化並執行指令碼』改為啟用後,發現有的機器可以,有的不成,而且設定後IE會提示不安全之類的。看起來很不優雅。果斷放棄修改IE設定。

仔細想想,自己寫的跟官方提供的一些控制元件理論上除了沒有數字簽名外,應該沒別的不同,於是嘗試增加數字簽名,當然這個是沒有認證的。嘗試後這個方案也失敗了。

找資料看到這樣一篇文章:http://www.xuebuyuan.com/758961.html

裡面講到,在IE的中級安全設定上,是允許指令碼安全的ActiveX建立並且不予警告的。那麼IE怎麼知道一個外掛式指令碼安全的呢?

①通過查詢ActiveX是否實現了IObjectSafety介面,並且返回指令碼安全;

②查詢ActiveX是否在登錄檔Component Category Manager裡表明自己實現了 CATID_SafeForInitializing 和 CATID_SafeForScripting。此方法修改DllRegisterServer函式

所以,問題的關鍵是我們自己的ActiveX控制元件 實現CATID_SafeForInitializing 和 CATID_SafeForScripting,以及IObjectSafety介面。

那就來吧。

①實現CATID_SafeForInitializing  和 CATID_Safeforscripting

XXX.h中宣告(以下XXX代表你的工程名,比如MyActiveX,則XXX.h表示MyActiveX.h)

包含標頭檔案檔案  #include "comcat.h"

HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription);
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid);

①xxxCtrl.h中宣告:

//ObjSafe
	DECLARE_INTERFACE_MAP()

	BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety)
	STDMETHOD_(HRESULT, GetInterfaceSafetyOptions)   (
		/*   [in]   */   REFIID   riid,
		/*   [out]   */   DWORD   __RPC_FAR   *pdwSupportedOptions,
		/*   [out]   */   DWORD   __RPC_FAR   *pdwEnabledOptions
	);

	STDMETHOD_(HRESULT, SetInterfaceSafetyOptions)   (
		/*   [in]   */   REFIID   riid,
		/*   [in]   */   DWORD   dwOptionSetMask,
		/*   [in]   */   DWORD   dwEnabledOptions
	);
	END_INTERFACE_PART(ObjSafe);
②xxxCtrl.cpp中實現:
const CATID CATID_SafeForScripting =
{ 0x7dd95801, 0x9882, 0x11cf, { 0x9f, 0xa9, 0x00, 0xaa, 0x00, 0x6c, 0x42, 0xc4 } };
const CATID CATID_SafeForInitializing =
{ 0x7dd95802, 0x9882, 0x11cf, { 0x9f, 0xa9, 0x00, 0xaa, 0x00, 0x6c, 0x42, 0xc4 } };

// 建立元件種類     
HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription)
{
	ICatRegister* pcr = NULL;
	HRESULT hr = S_OK;
	hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
	if (FAILED(hr)) return hr;
	// Make sure the HKCR\Component Categories\{..catid...}      
	// key is registered.      
	CATEGORYINFO catinfo;
	catinfo.catid = catid;
	catinfo.lcid = 0x0409; // english      
	// Make sure the provided description is not too long.      
	// Only copy the first 127 characters if it is.      
	int len = wcslen(catDescription);
	if (len>127) len = 127;
	wcsncpy(catinfo.szDescription, catDescription, len);
	// Make sure the description is null terminated.      
	catinfo.szDescription[len] = '\0';
	hr = pcr->RegisterCategories(1, &catinfo);
	pcr->Release();
	return hr;
}

// 註冊元件種類     
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
	// Register your component categories information.      
	ICatRegister* pcr = NULL;
	HRESULT hr = S_OK;
	hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
	if (SUCCEEDED(hr)) {
		// Register this category as being "implemented" by the class.      
		CATID rgcatid[1];
		rgcatid[0] = catid;
		hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
	}
	if (pcr != NULL) pcr->Release();
	return hr;
}
STDAPI DllRegisterServer(void) 函式中,新增:
// 標記控制元件初始化安全.      
	// 建立初始化安全元件種類     
	HRESULT hr = CreateComponentCategory(CATID_SafeForInitializing, L"Controls safely initializable from persistent data!");
	if (FAILED(hr)) return hr;
	// 註冊初始化安全     
	hr = RegisterCLSIDInCategory(BASED_CODE _tlid, CATID_SafeForInitializing);
	if (FAILED(hr)) return hr;
	// 標記控制元件指令碼安全     
	// 建立指令碼安全元件種類     
	hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls safely scriptable!");
	if (FAILED(hr)) return hr;
	// 註冊指令碼安全元件種類     
	hr = RegisterCLSIDInCategory(BASED_CODE _tlid, CATID_SafeForScripting);
	if (FAILED(hr)) return hr;
STDAPI DllUnregisterServer(void) 中新增:
// 刪除控制元件初始化安全入口. 
HRESULT hr = UnRegisterCLSIDInCategory(BASED_CODE _tlid, CATID_SafeForInitializing);
	if (FAILED(hr)) return hr;
	// 刪除控制元件指令碼安全入口     
	hr = UnRegisterCLSIDInCategory(BASED_CODE _tlid, CATID_SafeForScripting);
	if (FAILED(hr)) return hr;

xxxCtrl.h中新增:

//ObjSafe
	DECLARE_INTERFACE_MAP()

	BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety)
	STDMETHOD_(HRESULT, GetInterfaceSafetyOptions)   (
		/*   [in]   */   REFIID   riid,
		/*   [out]   */   DWORD   __RPC_FAR   *pdwSupportedOptions,
		/*   [out]   */   DWORD   __RPC_FAR   *pdwEnabledOptions
	);

	STDMETHOD_(HRESULT, SetInterfaceSafetyOptions)   (
		/*   [in]   */   REFIID   riid,
		/*   [in]   */   DWORD   dwOptionSetMask,
		/*   [in]   */   DWORD   dwEnabledOptions
	);
	END_INTERFACE_PART(ObjSafe);
xxxCtrl.cpp中新增:
//介面對映
BEGIN_INTERFACE_MAP(CRtmpDumpCtrlCtrl, COleControl)
	INTERFACE_PART(CRtmpDumpCtrlCtrl, IID_IObjectSafety, ObjSafe)
END_INTERFACE_MAP()

ULONG FAR EXPORT CRtmpDumpCtrlCtrl::XObjSafe::AddRef()
{
	METHOD_PROLOGUE(CRtmpDumpCtrlCtrl, ObjSafe)
	return pThis->ExternalAddRef();
}

ULONG FAR EXPORT CRtmpDumpCtrlCtrl::XObjSafe::Release()
{
	METHOD_PROLOGUE(CRtmpDumpCtrlCtrl, ObjSafe)
		return pThis->ExternalRelease();
}

HRESULT FAR EXPORT CRtmpDumpCtrlCtrl::XObjSafe::QueryInterface(REFIID iid, void FAR* FAR* ppvObj)
{
	METHOD_PROLOGUE(CRtmpDumpCtrlCtrl, ObjSafe)
	return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}

const DWORD dwSupportedBits = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
const DWORD dwNotSupportedBits = ~dwSupportedBits;

HRESULT   STDMETHODCALLTYPE
CRtmpDumpCtrlCtrl::XObjSafe::GetInterfaceSafetyOptions(
/* [in] */ REFIID riid,
/* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
/* [out] */ DWORD __RPC_FAR *pdwEnabledOptions)
{
	METHOD_PROLOGUE(CRtmpDumpCtrlCtrl, ObjSafe)
	HRESULT retval = ResultFromScode(S_OK);
	// does interface exist?   
	IUnknown FAR* punkInterface;
	retval = pThis->ExternalQueryInterface(&riid, (void **)&punkInterface);
	if (retval != E_NOINTERFACE)
	{ // interface exists   
		punkInterface->Release(); // release it--just checking!   
	}
	// we support both kinds of safety and have always both set, regardless of interface   
	*pdwSupportedOptions = *pdwEnabledOptions = dwSupportedBits;
	return retval; // E_NOINTERFACE if QI failed   
}

HRESULT STDMETHODCALLTYPE
CRtmpDumpCtrlCtrl::XObjSafe::SetInterfaceSafetyOptions(
/* [in] */ REFIID riid,
/* [in] */ DWORD dwOptionSetMask,
/* [in] */ DWORD dwEnabledOptions)
{
	METHOD_PROLOGUE(CRtmpDumpCtrlCtrl, ObjSafe)
		// does interface exist? 
	IUnknown FAR* punkInterface;
	pThis->ExternalQueryInterface(&riid, (void**)&punkInterface);
	if (punkInterface)
	{ // interface exists 
		punkInterface->Release(); // release it--just checking! 
	}
	else
	{ // interface doesn't exist 
		return ResultFromScode(E_NOINTERFACE);
	}

	// can't set bits we don't support 
	if (dwOptionSetMask & dwNotSupportedBits)
	{
		return ResultFromScode(E_FAIL);
	}

	// can't set bits we do support to zero 
	dwEnabledOptions &= dwSupportedBits;
	// (we already know there are no extra bits   in   mask   )   
	if ((dwOptionSetMask&dwEnabledOptions) != dwOptionSetMask)
	{
		return ResultFromScode(E_FAIL);
	}
	//don't need to change anything since we're always safe 
	return ResultFromScode(S_OK);
}

參考文章:

https://support.microsoft.com/zh-cn/kb/161873

https://msdn.microsoft.com/zh-cn/library/aa751977(v=vs.85).aspx

http://blog.sina.com.cn/s/blog_4f9fc08e01014ipt.html

http://www.xuebuyuan.com/758961.html

http://blog.csdn.net/aasmfox/article/details/38616997

烏雲的兩篇好文:

http://drops.wooyun.org/papers/5673

http://drops.wooyun.org/papers/7521


相關推薦

ActiveX控制元件localhost可以呼叫內外IP可以的解決辦法

開發ActiveX控制元件過程中遇到這樣的問題: 本機上開發完成後,用TstCon測試介面沒問題。js寫靜態頁面測試呼叫沒問題。但是給到web端開發,他們使用內網IP或者外網地址時,會報錯。如圖: 開始以為是IE本地設定的問題,把對ActiveX限制的都改為允許,但是試

[轉]寫的activex控制元件在IE中彈出安全警告的解決辦法~ (可用致敬)

//在控制元件標頭檔案中加入:  DECLARE_INTERFACE_MAP()  BEGIN_INTERFACE_PART(ObjectSafety, IObjectSafety)  STDMETHOD(GetInterfaceSafetyOptions)(REFII

JS利用ActiveX控制元件的方式即 Excel.Application,實現對word或者excel的列印

實現過程:先將需要列印的資料匯入到word或者excel中,再利用word或者excel的列印功能來實現web列印。    下面以excel為例實現如何列印的過程    將網頁中資料匯入excel中的方法有很多,這裡先介紹一種,利用ActiveX控制元件的方式,即 Exce

內外同時使用解決辦法

pri src 關機重啟 let 外網 ima 技術分享 查看 mask 1.內網IP地址為:10.1.14.56 子網掩碼:255.255.255.128 網關:10.1.14.126 2.外網為自動獲取IP地址 CMD命令:route -p add 10.1.1

android 開發 在oncreate()中獲取到控制元件的高度和寬度值為0解決辦法

大家很多時候需要在activity或者fragment的oncreate()方法中獲取宣告的空間的高度或者寬度,進行位置移動或者其他操作,但是當呼叫view.getHeight()或者view.getWidth()獲取的竟然為0。。。黑人問號。。。 其實很容易

MFC操作串列埠詳細 複製程式碼(ActiveX控制元件和Windows API函式)

/******************************************************************* *******函式功能:開啟串列埠裝置連結 *******函式名稱:OpenComm *******輸入引數:無 *******輸出引數:無 ***

C#(Winform) 當前執行緒在單執行緒單元中因此無法例項化 ActiveX 控制元件

解決方案: 1、在主執行緒中例項化此ActiveX控制元件 2、將建立此Active控制元件的執行緒設定為單執行緒。       Thread.ApartmentState 獲取或設定此執行緒的單元狀態。             newThread= new Thre

自己寫個activex控制元件如何知道他的classid(轉載)

在網頁裡用的時候需要知道他的classid我在程式碼中看到有 const GUID CDECL BASED_CODE _tlid = { 0x89201950, 0x2CAC, 0x4CF7, { 0x99, 0x8, 0x73, 0x38, 0x61, 0x41, 0xEF, 0xD2 }

解決問題win10“.dll(或者,ocx)控制元件已載入但對DllregisterServer的呼叫失敗錯誤程式碼為0x80070005”

重構機房的過程需要參考用VB生成的“機房收費系統”,安裝後需要執行的步驟: 第一:需要配置檔案DSN: 檔名稱:charge 伺服器:(local) 使用者名稱:sa 密碼:123456 資料庫:charge_sys 第二:附加資料庫 第三:需要註冊檔案“機房收費系統所需素材”中的3個控

關於ActiveX控制元件開發、js呼叫

控制元件製作: 32位控制元件製作 64位控制元件製作 參考:一、建立;二、介面;三、js呼叫 說明:64位控制元件的js呼叫我按上述教程製作,呼叫可以,但是控制元件中沒有文章中說的控制元件中顯示的

IE的安全設定中設成“啟用執行下載activeX控制元件”程式控制的實現的原理

(1)IE的安全屬性設定是放置在登錄檔的以下位置的: HKEY_USERS\UserName\Software\Microsoft\Windows\CurrentVersion\Internet Se

IE下部分activex控制元件無法正常呼叫的設定

最近將公司以前的OA從2005升級到2008後,發現在IE8下,公文處理這塊所使用的iweboffice沒辦法正常使用了.在除錯過程中發現activex控制元件的屬性是可以設定或獲取,可是一呼叫其方法就會報些物件不支援此方法. 再使用IE7測試,一點問題也沒有.都能正常的顯示

單機情況下IE瀏覽器訪問activeX控制元件出現紅叉問題的解決

本人也是剛接觸activeX控制元件,自己通過vs2010編寫了幾個簡單的例子,經測試工具測試過都可以用,在html檔案新增之後如果雙擊檔案用IE開啟,會有載入控制元件之類的提示,但是在瀏覽器中輸入url地址訪問時,在頁面中會出現一個紅叉,修改IE的設定也沒用。本文要解決的

為什麼修改了ie級別裡的activex控制元件為啟用後還是無法下載顯示還是ie級別設定太高?

如果下載外掛時下載不了,這樣設定,開啟IE選工具/Internet 選項/安全/自定義級別/設定中的ActiveX控制元件自動提示“禁用”。 對標記為可安全執行指令碼ActiveX控制元件執行指令碼“啟用” 對沒有標記為安全的ActiveX初始化和指令碼執行“啟用”(下載外掛

關於IE11瀏覽器能正確呼叫ActiveX控制元件解決辦法

 依次展開登錄檔到HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main分支 新建一個DWORD32值,並將其命名為TabProcGrowth,在彈出的對話方塊中輸入“0”或者“1”,需要相容的話需要將值設

關閉是否只檢視安全傳送的網頁內容提示框 和 是否允許執行軟體ActiveX控制元件和外掛提示框

關閉是否只檢視安全傳送的網頁內容提示框 最新編寫 爬蟲程式,執行程式後,電腦就總是出現下面這個提示框,一遍遍點“是”或“否”繁瑣又麻煩。我看得有點不耐煩了。於是就想個辦法不讓這個提示框總是出來提示。 解決辦法: 啟動 Internet Explorer

IE已限制此網頁執行可以訪問計算機的指令碼或ActiveX控制元件如何去除這個

     在頁面頭部加上       <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.

修改微軟TstCon容器原始碼使其支援Python指令碼和ActiveX控制元件互動

關於ActiveX和指令碼互動請看https://baike.baidu.com/item/ActiveX%E8%84%9A%E6%9C%AC%E7%BC%96%E7%A8%8B/3350788?fr=aladdin本

使用Delphi顯示ActiveX控制元件的屬性頁方法

unit Unit1;interfaceuses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  Dialogs, OleCtrls, MSCommLib_TLB, St

使用C#開發ActiveX控制元件封裝到瀏覽器使用出現找到XXXX.dll的異常解決

背景: 專案中使用C#開發一款元件,用於Tomcat+Jsp專案中,在瀏覽器中通過Active元件的方式呼叫,部分功能會出現找不到 XXX.dll的問題。 異常原因: 通過瀏覽器呼叫C# Active控制元件時,預設到IE瀏覽器的Bin目錄下尋找 控制元件的dll檔案,