How to declare the control as a script security 2004-10-18 19:49:33 (Article category: C )
#Basic skills: Create Safe Initialization & Scripting ActiveX Control When you create an ActiveX control used in a web browser, you need to declare the control as script security, otherwise the browser will securely prompt when the control is loaded and the script interacts, affects usage:
Creating an initialization / script security ActiveX control usually has two ways: implementing the IObjectsafety interface of the control: # # 客户 客户 注 注:: # Implement the IObjectsafety interface below the IObjectsafety, the interface mainly defines two pure virtual functions - GetInterfaceSafetyOptions and SetInterfaceSafetyOptions: //Objsafe.h// Option bit definitions for IObjectSafety: # defineINTERFACESAFE_FOR_UNTRUSTED_CALLER0x00000001 // Caller of interface may be untrusted # defineINTERFACESAFE_FOR_UNTRUSTED_DATA0x00000002 /. / Data passed into interface may be untrusted. // {CB5BDC81-93C1-11cf-8F20-00805F2CD064} DEFINE_GUID (IID_IObjectSafety, 0xcb5bdc81, 0x93c1, 0x11cf, 0x8f, 0x20, 0x0, 0x80, 0x5f, 0x2c, 0xd0, 0x64 Interface IObjectsafety: Public IUNKNOWN {public: virtual hresult __stdcall getInterfacesafetyOptions ( / * [in] * / refiid riid, / * [out] * / DWORD __RPC_FAR * PDWSUPPORTEDOPTIONS, / * [out] * / dword __rpc_far * pdwenabledoptions) = 0; virtual hresult __stdcall setInterfaceSafetyOptions ( / * [in] * / Refiid riid, / * [in] * / dword dwoptionSetmask, / * [in] * / dword dwenable dOptions) = 0;}; GetInterfaceSafetyOptions return security identifier for the control: INTERFACESAFE_FOR_UNTRUSTED_CALLER safe for scripting interface declaration statement INTERFACESAFE_FOR_UNTRUSTED_DATA request control interface allows the container to initialize and configure itself to the initialization script security safe SetInterfaceSafetyOptions. Browser When loading an ActiveX control, the browser will first detect whether the control supports the IObjectsafety interface, if support, the browser first calls iObjectsafety :: SETINTERFACESAFETYOPTIONS complete control initialization, continue to call IOBJECTSAFETY :: GetInterfaceSafetyOptions if the control supports script interacts.
● If ATL, can be achieved IObjectSafety: // MyCtrlClass.hclass ATL_NO_VTABLE CMyCtrlClass: ... public IObjectSafetyImpl
#endif // L_IMPL_OBJECTSAFET // ProjectNameCtrl.cpp # ifdef L_IMPL_OBJECTSAFETY BEGIN_INTERFACE_MAP (CProjectNameCtrl, COleControl) INTERFACE_PART (CProjectNameCtrl, IID_IObjectSafety, ObjectSafety) END_INTERFACE_MAP () #endif // L_IMPL_OBJECTSAFETY # ifdef L_IMPL_OBJECTSAFETY // Implementation of IObjectSafety STDMETHODIMP CProjectNameCtrl :: XObjectSafety: : GetInterfaceSafetyOptions (REFIID riid, DWORD __RPC_FAR * pdwSupportedOptions, DWORD __RPC_FAR * pdwEnabledOptions) {METHOD_PROLOGUE_EX (CProjectNameCtrl, 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_IPERSISTREAMINIT || 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;
}} {{ // 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 cprojectnamectrl :: xobjectsafety :: setInterfacesafetyOptions (refiid riid, dword dwoptionSetmask, DWORD dwEnabledOptions) {METHOD_PROLOGUE_EX (CProjectNameCtrl, 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 isn't supported. return s_ok; } // do we support the specified interface? (null == pthis-> getInterface & riid) {trace1 ("% s is not support./n", szguid); return e_fail; } IF (ri ID == 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) cprojectnamectrl :: xobjectsafety :: addRef () {Method_Prologue_ex_ ( CProjectNameCtrl, ObjectSafety) return (ULONG) pThis-> ExternalAddRef ();} STDMETHODIMP_ (ULONG) CProjectNameCtrl :: XObjectSafety :: Release () {METHOD_PROLOGUE_EX_ (CProjectNameCtrl, ObjectSafety) return (ULONG) pThis-> ExternalRelease ();} STDMETHODIMP CProjectNameCtrl :: XObjectSafety :: QueryInterface (REFIID iid, LPVOID * ppvObj) {METHOD_PROLOGUE_EX_ (CProjectNameCtrl, ObjectSafety) return (HRESULT) pThis-> ExternalQueryInterface (& iid, ppvObj);} #endif // l_impl_objectsafety pay attention to the project attribute / C / C / preprocessor Polyprocessing definition: l_impl_objectsafety # Modify the client registry If the control is implemented to implement the IObjectsafety interface, then the browser will further call the ICATINFORMATION :: ISCLASSOFCATEGORIES Query System Registry HKEY_CLASES_ROOT / Component Categories / {.. catid ...}, check control Support for a given component type (Component Category). If the control already uses the "Component Categories Manager" to register your own registration as a security. In order to create the correct component type subkey in the registry, the following three steps are usually implemented: Create an instance of "Component Categories Manager" and get the ICATREGISTER interface pointer; instantiate the CategoryInfo structure and populate the appropriate member Call ICATINFORMATION :: IsclassOfCategories with the CategoryInfo address. Add #include
Then add the following functions in the implementation file of the App class (Projectname.cpp): //projectname.cppconst Guid CDECL CLSID_SAFEITEM = {0x3B43D84B, 0x05Be, 0x4cb3, {0xB6, 0x82, 0xE1, 0x60, 0xc3, 0x8b, 0xA0, 0x88}}; // Note that this GUID must be the same as the control's CLSID! // Do not equal the const guid cdecl based_code _tlid // version control const word _wvermajor = 1; //// ... initInstance () and exitInstance () // creation component type 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 . Catinfo.catid = catid; catinfo.lcid = 0x0409; // 中文 // Make Sure 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_ICATREGOSTER, (Void **) & PCR); IF (ackedeeded (HR)) { // register this category as being "import" by the Class. Catid Rgcatid [1];
Rgcatid [0] = catid; hr = PCR-> RegisterClassImplcategories (CLSID, 1, RGCATID); } IF (PCR! = Null) PCR-> release (); return hr;} // unloader assembly type 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 "import" by the class. catid rgcatid [ 1]; Rgcatid [0] = Catid; hr = PCR-> UnregisterClassImplcategories (CLSID, 1, RGCATID); } IF (PCR! = Null) PCR-> Release (); return hr;} STDAPI DllRegisterServer (void) {HRESULT hr; AFX_MANAGE_STATE (_afxModuleAddrThis); if (! AfxOleRegisterTypeLib (AfxGetInstanceHandle (), _tlid)) return ResultFromScode (SELFREG_E_TYPELIB) ; IF (! ColeObjectFactoryEx :: UpdateRegistryll (True)) RETURN RESULTFROMSCODE (Selfreg_e_class); // Tag Control Initialization Safety. // Create Initialization Security Component Type hr = CreateComp OneTcategory (Catid_safeForInitializing, L "Controls Safely Initializable from Persistent Data!"); IF (Failed (HR)) return HR; // Register Initialization Safety hr = RegisterCLSIDInCategory (CLSID_SafeItem, CATID_SafeForInitializing); if (FAILED (hr)) return hr; // marking controls safe for scripting // create scripts security component species hr = CreateComponentCategory (CATID_SafeForScripting, L "Controls Safely Scriptable!"); IF (Failed (HR)) return HR; // Register Script Security Component Type hr = registerclsidIndIncategory (CLSID_SAFEITEM, CACID_SAFEFORScripting); IF (failed HR)) return hr; return noerror;} stdapi dllunregisterserver (void) {hResult HR; AFX_manage_state (_AFXModuleAdDRTHIS);