Design of ActiveX Control Using MFC-Step 2

Source: Internet
Author: User
Tags class manager what interface
The web page does not know much about ActiveX controls, but it seems that ActiveX controls account for a considerable proportion of all questions about ActiveX controls on the web page, security warnings popped up on the webpage.

This question is not complicated. You can find a large answer by searching on the Internet. It is a huge copy of the article.

References:
Http://www.newebug.com/article/cpp/2207.shtml
Http://www.ccw.com.cn/htm/app/aprog/01_3_29_4.asp
Http://msdn.microsoft.com/library/default.asp? Url =/library/en-us/DNA xctrl/html/msdn_signmark.asp

Hey, it's just a copy. Let's copy it.

Create a control tix

Method 1: Use "Component Categories Manager" to register itself on the customer's machine for security.

1. In tix. cpp
# Include "objsafe. h"
# Include "comcat. h"

2. Add the clsid definition of the control in tix. cpp.
Const guid cdecl CLSID_SafeItem =
{0x06aa1f79, 0x1874, 0x445c, {0xb9, 0x0a, 0x23, 0x36, 0xb7, 0x39, 0xf2, 0x54 }};
// Note that the GUID must be the same as the CLSID of the control!
// You can copy and organize them from the macro of the initialization class factory.
// IMPLEMENT_OLECREATE_EX (CTixCtrl, "TIX. TixCtrl.1 ",
// 0x6aa1f79, 0x1874, 0x445c, 0xb9, 0xa, 0x23, 0x36, 0xb7, 0x39, 0xf2, 0x54)

3. Add three functions in tix. cpp to get the component class manager and register yourself.

// Create Component Types
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;
}

// Register the component type
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;
}

// Uninstall Component Types
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 ))
{
// Unregister this category as being "implemented" by the class.
CATID rgcatid [1];
Rgcatid [0] = catid;
Hr = pcr-> UnRegisterClassImplCategories (clsid, 1, rgcatid );
}

If (pcr! = NULL)
Pcr-> Release ();

Return hr;
}

4. Modify the DllRegisterServer and DllUnregisterServer to register security when registering the control

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 );

HRESULT hr;
// Tag control initialization security.
// Create an initialized security component type
Hr = CreateComponentCategory (CATID_SafeForInitializing,
L "Controls safely initializable from persistent data! ");
If (FAILED (hr ))
Return hr;
// Register for initialization Security
Hr = RegisterCLSIDInCategory (CLSID_SafeItem, CATID_SafeForInitializing );
If (FAILED (hr ))
Return hr;

// Flag control Script Security
// Create a script security component type
Hr = CreateComponentCategory (CATID_SafeForScripting, L "Controls safely scriptable! ");
If (FAILED (hr ))
Return hr;
// Register the script security component type
Hr = RegisterCLSIDInCategory (CLSID_SafeItem, CATID_SafeForScripting );
If (FAILED (hr ))
Return hr;

Return NOERROR;
}

//////////////////////////////////////// /////////////////////////////////////
// DllUnregisterServer-Removes entries from the system registry

STDAPI DllUnregisterServer (void)
{
AFX_MANAGE_STATE (_ afxModuleAddrThis );

HRESULT hr;
// Delete the control initialization security entry.
Hr = UnRegisterCLSIDInCategory (CLSID_SafeItem, CATID_SafeForInitializing );
If (FAILED (hr ))
Return hr;
// Security entry for deleting Control Scripts
Hr = UnRegisterCLSIDInCategory (CLSID_SafeItem, CATID_SafeForScripting );
If (FAILED (hr ))
Return hr;

If (! AfxOleUnregisterTypeLib (_ tlid, _ wVerMajor, _ wVerMinor ))
Return ResultFromScode (SELFREG_E_TYPELIB );

If (! COleObjectFactoryEx: UpdateRegistryAll (FALSE ))
Return ResultFromScode (SELFREG_E_CLASS );

Return NOERROR;
}

Okay, that's OK. Now you can try it on the webpage.

Method 2: implement the IObjectSafety interface of the control.

1. First uninstall the control with regsvr32/u. In fact, it is to cancel the registration of control security, and then comment out the registration code we added in the preceding aspects of control security in DllRegisterServer and DllUnregisterServer.

2. Add the nested class declaration to tixctl. h of the control.
DECLARE_EVENT_MAP ()

BEGIN_INTERFACE_PART (ObjectSafety, IObjectSafety)
STDMETHOD (GetInterfaceSafetyOptions) (REFIID riid, DWORD _ RPC_FAR * pdwSupportedOptions, DWORD _ RPC_FAR * pdwEnabledOptions );
STDMETHOD (SetInterfaceSafetyOptions) (REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions );
END_INTERFACE_PART (ObjectSafety)
DECLARE_INTERFACE_MAP ()

Don't forget # include "objsafe. h"

3. Add nested class implementation to tixctl. cpp of the control.
STDMETHODIMP CTixCtrl: XObjectSafety: GetInterfaceSafetyOptions (
REFIID riid,
DWORD _ RPC_FAR * pdwSupportedOptions,
DWORD _ RPC_FAR * pdwEnabledOptions)
{
METHOD_PROLOGUE_EX (CTixCtrl, ObjectSafety)

If (! PdwSupportedOptions |! PdwEnabledOptions)
{
Return E_POINTER;
}

* PdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
* PdwEnabledOptions = 0;

If (NULL = pThis-> GetInterface (& riid ))
{
TRACE ("Requested interface is not supported./n ");
Return E_NOINTERFACE;
}

// What interface is being checked out anyhow?
OLECHAR szGUID [39];
Int I = StringFromGUID2 (riid, szGUID, 39 );

If (riid = IID_IDispatch)
{
// Client wants to know if object is safe for scripting
* PdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
Return S_ OK;
}
Else if (riid = IID_IPersistPropertyBag
| Riid = IID_IPersistStreamInit
| Riid = IID_IPersistStorage
| Riid = IID_IPersistMemory)
{
// Those are the persistence interfaces COleControl derived controls support
// As indicated in AFXCTL. H
// Client wants to know if object is safe for initializing from persistent data
* PdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
Return S_ OK;
}
Else
{
// Find out what interface this is, and decide what options to enable
TRACE ("We didn't account for the safety of this interface, and it's one we support.../n ");
Return E_NOINTERFACE;
}
}

STDMETHODIMP CTixCtrl: XObjectSafety: SetInterfaceSafetyOptions (
REFIID riid,
DWORD dwOptionSetMask,
DWORD dwEnabledOptions)
{
METHOD_PROLOGUE_EX (CTixCtrl, ObjectSafety)

OLECHAR szGUID [39];
// What is this interface anyway?
// We can do a quick lookup in the registry under HKEY_CLASSES_ROOT/Interface
Int I = StringFromGUID2 (riid, szGUID, 39 );

If (0 = dwOptionSetMask & 0 = dwEnabledOptions)
{
// The control certainly supports NO requests through the specified interface
// So it's safe to return S_ OK even if the interface isn't supported.
Return S_ OK;
}

// Do we support the specified interface?
If (NULL = pThis-> GetInterface (& riid ))
{
TRACE1 ("% s is not support./n", szGUID );
Return E_FAIL;
}

If (riid = IID_IDispatch)
{
TRACE ("Client asking if it's safe to call through IDispatch./n ");
TRACE ("In other words, is the control safe for scripting? /N ");
If (INTERFACESAFE_FOR_UNTRUSTED_CALLER = dwOptionSetMask & INTERFACESAFE_FOR_UNTRUSTED_CALLER = dwEnabledOptions)
{
Return S_ OK;
}
Else
{
Return E_FAIL;
}
}
Else if (riid = IID_IPersistPropertyBag
| Riid = IID_IPersistStreamInit
| Riid = IID_IPersistStorage
| Riid = IID_IPersistMemory)
{
TRACE ("Client asking if it's safe to call through IPersist *./n ");
TRACE ("In other words, is the control safe for initializing from persistent data? /N ");

If (INTERFACESAFE_FOR_UNTRUSTED_DATA = dwOptionSetMask & INTERFACESAFE_FOR_UNTRUSTED_DATA = dwEnabledOptions)
{
Return NOERROR;
}
Else
{
Return E_FAIL;
}
}
Else
{
TRACE1 ("We didn't account for the safety of % s, and it's one we support.../n", szGUID );
Return E_FAIL;
}
}

STDMETHODIMP _ (ULONG) CTixCtrl: XObjectSafety: AddRef ()
{
METHOD_PROLOGUE_EX _ (CTixCtrl, ObjectSafety)
Return (ULONG) pThis-> ExternalAddRef ();
}

STDMETHODIMP _ (ULONG) CTixCtrl: XObjectSafety: Release ()
{
METHOD_PROLOGUE_EX _ (CTixCtrl, ObjectSafety)
Return (ULONG) pThis-> ExternalRelease ();
}

STDMETHODIMP CTixCtrl: XObjectSafety: QueryInterface (
REFIID iid, LPVOID * ppvObj)
{
METHOD_PROLOGUE_EX _ (CTixCtrl, ObjectSafety)
Return (HRESULT) pThis-> ExternalQueryInterface (& iid, ppvObj );
}

4. Join the interface ing table
Add declaration in tixctl. h
DECLARE_INTERFACE_MAP ()
Add tixctl. cpp

BEGIN_INTERFACE_MAP (CTixCtrl, COleControl)
INTERFACE_PART (CTixCtrl, IID_IObjectSafety, ObjectSafety)
END_INTERFACE_MAP ()

Okay. Try it. No problem.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.