Cómo marcar controles ActiveX de MFC como seguros para el scripting y la inicialización


Resumen


De forma predeterminada, los controles ActiveX de MFC no se marcan como seguros para el scripting y seguros para inicialización. Esto se hace evidente cuando el control se ejecuta en Internet Explorer con el nivel de seguridad establecido en medio o alto. En cualquiera de estos modos, es posible que se muestren advertencias de que los datos del control no son seguros o que el control puede no ser seguro para los scripts que se usan. Hay dos métodos que un control puede usar para eliminar estos errores. El primero implica el control que implementa la interfaz IObjectSafety y es útil para los controles que desea cambiar su comportamiento y se convierten en "seguros" si se ejecutan en el contexto de un explorador de Internet. El segundo implica modificar la función DllRegisterServer del control para marcar el control "seguro" en el registro. En este artículo se trata el segundo de estos métodos. El primer método, la implementación de la interfaz IObjectSafety, se trata en el SDK del cliente de Internet. Ten en cuenta que un control solo debe marcarse como seguro si, de hecho, es seguro. Para obtener una descripción de esta información, consulte la documentación del SDK del cliente de Internet. Vea "inicialización y scripting seguros para controles ActiveX" en la sección desarrollo de componentes.Nota En este artículo no se describe cómo marcar un control como seguro para descargarlo. Para obtener más información sobre la descarga de código y la firma de código, consulta el SDK del cliente de Internet.

Más información


Siga estos pasos para marcar el control ActiveX de MFC como seguro para las secuencias de comandos y la inicialización:
  1. Implemente las funciones de ayuda de CreateComponentCategory y RegisterCLSIDInCategory agregando los siguientes archivos cathelp. h y cathelp. cpp al proyecto.

    Cathelp.h

          #include "comcat.h"      // Helper function to create a component category and associated      // description      HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription);      // Helper function to register a CLSID as belonging to a component      // category      HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid);

    Cathelp.cpp

          #include "comcat.h"      // Helper function to create a component category and associated      // description      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;      }      // Helper function to register a CLSID as belonging to a component      // category      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;      }
  2. Modifique el DllRegisterServer para marcar el control como seguro. Busque la implementación de DllRegisterServer en un archivo. cpp de su proyecto. Tendrá que agregar varias cosas a este archivo. cpp. Incluya el archivo que implementa CreateComponentCategory y RegisterCLSIDInCategory:
          #include "CatHelp.h"
    Defina el GUID asociado a las categorías de los componentes de seguridad:
          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}};
    Defina el GUID asociado a su control. Para que resulte más sencillo, puede tomar prestado el GUID de la macro IMPLEMENT_OLECREATE_EX en el archivo. cpp principal del control. Ajuste el formato ligeramente para que tenga el siguiente aspecto:
          const GUID CDECL BASED_CODE _ctlid =      { 0x43bd9e45, 0x328f, 0x11d0,              { 0xa6, 0xb9, 0x0, 0xaa, 0x0, 0xa7, 0xf, 0xc2 } };
    Para marcar el control como seguro para scripting e inicialización, modifique la función DllRegisterServer de la siguiente manera:
          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);          if (FAILED( CreateComponentCategory(                  CATID_SafeForScripting,                  L"Controls that are safely scriptable") ))                return ResultFromScode(SELFREG_E_CLASS);          if (FAILED( CreateComponentCategory(                  CATID_SafeForInitializing,                  L"Controls safely initializable from persistent data") ))                return ResultFromScode(SELFREG_E_CLASS);          if (FAILED( RegisterCLSIDInCategory(                  _ctlid, CATID_SafeForScripting) ))                return ResultFromScode(SELFREG_E_CLASS);          if (FAILED( RegisterCLSIDInCategory(                  _ctlid, CATID_SafeForInitializing) ))                return ResultFromScode(SELFREG_E_CLASS);          return NOERROR;      }
Normalmente, la función DllUnregisterServer no se modifica por estas dos razones:
  • No querrás quitar una categoría de componente porque otros controles pueden estar en uso.
  • Aunque se ha definido una función UnRegisterCLSIDInCategory, de forma predeterminada DllUnregisterServer quita completamente la entrada del control del registro. Por lo tanto, quitar la categoría del registro del control es de poco uso.
Después de compilar y registrar el control, debe buscar las siguientes entradas en el registro:
   HKEY_CLASSES_ROOT\Component   Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}   HKEY_CLASSES_ROOT\Component   Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}   HKEY_CLASSES_ROOT\CLSID\{"your controls GUID"}\Implemented   Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}   HKEY_CLASSES_ROOT\CLSID\{"your controls GUID"}\Implemented   Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4} 

Referencias


SDK de cliente de Internet: inicialización y scripting seguros para el desarrollo de componentes para controles ActiveX