ActiveXコントロールは安全な初期化とスクリプトを実現します。
セキュリティの警告やエラーメッセージのないIEに成功してロードできるActiveXコントロールを作成するには、セキュリティの初期化とスクリプトが必要です。基本的には、すべての仕事はDllRegister ServerとDllUniregister Serverの2つの関数で行われます。次は、ActiveXコントロールを「安全」コントロールに変えていきます。
1.XXXを編集します。cppは下記のコードを追加します。そのうち、CLSID_SafeItemの値はXCtrl.cppのIMPLEMENT_と同じです。OECREATE_EXが一致しています。これはあなたのActiveXコントロールと同じです。同様に、あなたのHTMLページのOBJECTIDタグの中のCLSIDとも一致するべきです。
以下は私のプロジェクトの中で安全な初期化とスクリプトのために追加されたコードです。元のIDEが自動的に生成した部分と比較してそれらの部分が追加されています。どの部分がActiveXコントロールを作成する時に自動的に発生するコードですか?
同様にXXXにあります。cppは下記のコードを追加します。
3.DllRegister Server関数を修正する必要があります。元のIDEが自動的に生成した部分と比較して、追加する部分を確認できます。
1.XXXを編集します。cppは下記のコードを追加します。そのうち、CLSID_SafeItemの値はXCtrl.cppのIMPLEMENT_と同じです。OECREATE_EXが一致しています。これはあなたのActiveXコントロールと同じです。同様に、あなたのHTMLページのOBJECTIDタグの中のCLSIDとも一致するべきです。
以下は私のプロジェクトの中で安全な初期化とスクリプトのために追加されたコードです。元のIDEが自動的に生成した部分と比較してそれらの部分が追加されています。どの部分がActiveXコントロールを作成する時に自動的に発生するコードですか?
// CCEA.cpp : CCCEAApp DLL 。
#include "stdafx.h"
#include "CCEA.h"
#include "ComCat.h"
#include "strsafe.h"
#include "ObjSafe.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CCCEAApp theApp;
/*const GUID CDECL BASED_CODE _tlid =
{ 0x5E5EBDFC, 0x6D73, 0x4652, { 0x85, 0x3, 0x3F, 0xBF, 0x94, 0x7A, 0xCA, 0xD5 } };*/
const GUID CDECL BASED_CODE _tlid =
{ 0x1f7c5839, 0x4814, 0x4f2b, { 0xbd, 0x9e, 0x81, 0xd6, 0x2b, 0x59, 0x96, 0xaf } };
const GUID CDECL CLSID_SafeItem =
{ 0x6f82c754, 0x6c31, 0x43ea, { 0x98, 0x18, 0xe9, 0x5a, 0xd4, 0xe8, 0x72, 0xfc } };
const WORD _wVerMajor = 1;
const WORD _wVerMinor = 0;
// CCCEAApp::InitInstance - DLL
BOOL CCCEAApp::InitInstance()
{
BOOL bInit = COleControlModule::InitInstance();
if (bInit)
{
// TODO: 。
}
return bInit;
}
// CCCEAApp::ExitInstance - DLL
int CCCEAApp::ExitInstance()
{
// TODO: 。
return COleControlModule::ExitInstance();
}
// Component Categories
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;
// HKCR\Component Categories\{..catid...}
CATEGORYINFO catinfo;
catinfo.catid = catid;
catinfo.lcid = 0x0409; // english
//size_t len;
// 。
// 127 。
// StringCchLength catDescription 。
//
//hr = StringCchLength(catDescription, STRSAFE_MAX_CCH, &len);
int len = wcslen(catDescription);
if (SUCCEEDED(hr))
{
if (len>127)
{
len = 127;
}
}
else
{
// TODO: Write an error handler;
}
wcsncpy(catinfo.szDescription, catDescription, len);
//hr = StringCchCopy(catinfo.szDescription, len + 1, catDescription);
// .
//catinfo.szDescription[len + 1] = '\0';
catinfo.szDescription[len] = '/0';
hr = pcr->RegisterCategories(1, &catinfo);
pcr->Release();
return hr;
}
2.そして登録コンポーネントの分類情報を追加する必要があります。同様にXXXにあります。cppは下記のコードを追加します。
// CLSID Component Categories implemented Categories
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
//
ICatRegister *pcr = NULL ;
HRESULT hr = S_OK ;
hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
if (SUCCEEDED(hr))
{
CATID rgcatid[1] ;
rgcatid[0] = catid;
hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
}
if (pcr != NULL)
pcr->Release();
return hr;
}
// CLSID implemented Categories , ,
HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
ICatRegister *pcr = NULL ;
HRESULT hr = S_OK ;
hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
if (SUCCEEDED(hr))
{
CATID rgcatid[1] ;
rgcatid[0] = catid;
hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid);
}
if (pcr != NULL)
pcr->Release();
return hr;
}
この二つの方法は全く新しいものを追加しなければならない。3.DllRegister Server関数を修正する必要があります。元のIDEが自動的に生成した部分と比較して、追加する部分を確認できます。
// DllRegisterServer -
STDAPI DllRegisterServer(void)
{
AFX_MANAGE_STATE(_afxModuleAddrThis);
if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
return ResultFromScode(SELFREG_E_TYPELIB);
if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
return ResultFromScode(SELFREG_E_CLASS);
// “ ” , CLSID
HRESULT hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls safely scriptable!");
if (FAILED(hr))
return hr;
// “ ” , CLSID
hr = CreateComponentCategory(CATID_SafeForInitializing, L"Controls safely initializable from persistent data!");
if (FAILED(hr))
return hr;
// CLSID , “ ”
hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);
if (FAILED(hr))
return hr;
// CLSID , “ ”
hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);
if (FAILED(hr))
return hr;
return NOERROR;
}
4.最後にDllUniregister Server関数を修正し、元のIDEが自動的に生成した部分と比較して、追加する部分を確認することができます。// DllUnregisterServer -
STDAPI DllUnregisterServer(void)
{
AFX_MANAGE_STATE(_afxModuleAddrThis);
if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
return ResultFromScode(SELFREG_E_TYPELIB);
if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
return ResultFromScode(SELFREG_E_CLASS);
// .
HRESULT hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);
if (FAILED(hr))
return hr;
//
hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);
if (FAILED(hr))
return hr;
return NOERROR;
}
以上の部分は他のコントロールの工程では多重化できます。CLSID_に注意する必要があります。SafeItemの正確性は、最終的にコントロールのセキュリティの初期化とスクリプトを実現しました。XXX(ここはコントロールのプロジェクト名です。)で、cppの中の完全なコードは以下の通りです。// CCEA.cpp : CCCEAApp DLL 。
#include "stdafx.h"
#include "CCEA.h"
#include "ComCat.h"
#include "strsafe.h"
#include "ObjSafe.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CCCEAApp theApp;
/*const GUID CDECL BASED_CODE _tlid =
{ 0x5E5EBDFC, 0x6D73, 0x4652, { 0x85, 0x3, 0x3F, 0xBF, 0x94, 0x7A, 0xCA, 0xD5 } };*/
const GUID CDECL BASED_CODE _tlid =
{ 0x1f7c5839, 0x4814, 0x4f2b, { 0xbd, 0x9e, 0x81, 0xd6, 0x2b, 0x59, 0x96, 0xaf } };
const GUID CDECL CLSID_SafeItem =
{ 0x6f82c754, 0x6c31, 0x43ea, { 0x98, 0x18, 0xe9, 0x5a, 0xd4, 0xe8, 0x72, 0xfc } };
const WORD _wVerMajor = 1;
const WORD _wVerMinor = 0;
// CCCEAApp::InitInstance - DLL
BOOL CCCEAApp::InitInstance()
{
BOOL bInit = COleControlModule::InitInstance();
if (bInit)
{
// TODO: 。
}
return bInit;
}
// CCCEAApp::ExitInstance - DLL
int CCCEAApp::ExitInstance()
{
// TODO: 。
return COleControlModule::ExitInstance();
}
// Component Categories
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;
// HKCR\Component Categories\{..catid...}
CATEGORYINFO catinfo;
catinfo.catid = catid;
catinfo.lcid = 0x0409; // english
//size_t len;
// 。
// 127 。
// StringCchLength catDescription 。
//
//hr = StringCchLength(catDescription, STRSAFE_MAX_CCH, &len);
int len = wcslen(catDescription);
if (SUCCEEDED(hr))
{
if (len>127)
{
len = 127;
}
}
else
{
// TODO: Write an error handler;
}
wcsncpy(catinfo.szDescription, catDescription, len);
//hr = StringCchCopy(catinfo.szDescription, len + 1, catDescription);
// .
//catinfo.szDescription[len + 1] = '\0';
catinfo.szDescription[len] = '/0';
hr = pcr->RegisterCategories(1, &catinfo);
pcr->Release();
return hr;
}
// CLSID Component Categories implemented Categories
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
//
ICatRegister *pcr = NULL ;
HRESULT hr = S_OK ;
hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
if (SUCCEEDED(hr))
{
CATID rgcatid[1] ;
rgcatid[0] = catid;
hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
}
if (pcr != NULL)
pcr->Release();
return hr;
}
// CLSID implemented Categories , ,
HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
ICatRegister *pcr = NULL ;
HRESULT hr = S_OK ;
hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
if (SUCCEEDED(hr))
{
CATID rgcatid[1] ;
rgcatid[0] = catid;
hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid);
}
if (pcr != NULL)
pcr->Release();
return hr;
}
// DllRegisterServer -
STDAPI DllRegisterServer(void)
{
AFX_MANAGE_STATE(_afxModuleAddrThis);
if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
return ResultFromScode(SELFREG_E_TYPELIB);
if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
return ResultFromScode(SELFREG_E_CLASS);
// “ ” , CLSID
HRESULT hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls safely scriptable!");
if (FAILED(hr))
return hr;
// “ ” , CLSID
hr = CreateComponentCategory(CATID_SafeForInitializing, L"Controls safely initializable from persistent data!");
if (FAILED(hr))
return hr;
// CLSID , “ ”
hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);
if (FAILED(hr))
return hr;
// CLSID , “ ”
hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);
if (FAILED(hr))
return hr;
return NOERROR;
}
// DllUnregisterServer -
STDAPI DllUnregisterServer(void)
{
AFX_MANAGE_STATE(_afxModuleAddrThis);
if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
return ResultFromScode(SELFREG_E_TYPELIB);
if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
return ResultFromScode(SELFREG_E_CLASS);
// .
HRESULT hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);
if (FAILED(hr))
return hr;
//
hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);
if (FAILED(hr))
return hr;
return NOERROR;
}
この時には、「安全ではない」という警告やエラーメッセージがないIEに成功したActiveXコントロールを作成することができます。