Marcar controles ActiveX do MFC como seguros para scripts e inicialização

Este artigo descreve como marcar os controles ActiveX do MFC como Seguros para Scripts e Inicialização.

Versão original do produto: Controles ActiveX do MFC
Número de KB original: 161873

Resumo

Por padrão, os controles ActiveX do MFC não são marcados como seguros para scripts e seguros para inicialização. Isso se torna evidente quando o controle é executado na Internet Explorer com o nível de segurança definido como médio ou alto. Em qualquer um desses modos, os avisos podem ser exibidos de que os dados do controle não são seguros ou que o controle pode não ser seguro para scripts usarem.

Há dois métodos que um controle pode usar para eliminar esses erros. O primeiro envolve o controle que implementa a IObjectSafety interface e é útil para controles que gostariam de alterar seu comportamento e se tornar seguros se executados no contexto de um Navegador da Internet. O segundo envolve modificar a função do DllRegisterServer controle para marcar o controle seguro no registro. Este artigo aborda o segundo desses métodos. O primeiro método, implementando a IObjectSafety interface, é abordado no SDK do Cliente da Internet.

Tenha em mente que um controle só deve ser marcado como seguro se for, de fato, seguro. Consulte a documentação do SDK do Cliente da Internet para obter uma descrição disso. Consulte Inicialização segura e script para controles ActiveX na seção Desenvolvimento de Componentes.

Observação

Este artigo não aborda como marcar um controle seguro para download. Para obter mais informações sobre download de código e assinatura de código, consulte o SDK do Cliente da Internet.

Mais informações

Siga estas etapas para marcar o controle ActiveX do MFC como seguro para scripts e seguro para inicialização:

  1. Implemente as CreateComponentCategory funções auxiliares e RegisterCLSIDInCategory adicionando os seguintes arquivos cathelp.h e cathelp.cpp ao seu projeto.

    • 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 o DllRegisterServer para marcar o controle como seguro. Localize a implementação de DllRegisterServer em um arquivo .cpp em seu projeto. Você precisará adicionar várias coisas a este arquivo .cpp. Inclua o arquivo que implementa CreateComponentCategory e RegisterCLSIDInCategory:

    #include "CatHelp.h"
    

    Defina o GUID associado às categorias de componentes de segurança:

    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 o GUID associado ao controle. Para simplificar, você pode emprestar o GUID da IMPLEMENT_OLECREATE_EX macro no arquivo main .cpp para o controle. Ajuste um pouco o formato para que ele se pareça com o seguinte:

    const GUID CDECL BASED_CODE _ctlid =
    { 0x43bd9e45, 0x328f, 0x11d0,
    { 0xa6, 0xb9, 0x0, 0xaa, 0x0, 0xa7, 0xf, 0xc2 } };
    

    Para marcar seu controle como Seguro para Scripts e Inicialização, modifique a função da DllRegisterServer seguinte maneira:

    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, você não modificaria a DllUnregisterServer função por esses dois motivos:

    • Você não gostaria de remover uma categoria de componente porque outros controles podem estar usando-a.

    • Embora haja uma UnRegisterCLSIDInCategory função definida, por padrão DllUnregisterServer remove totalmente a entrada do controle do registro. Portanto, a remoção da categoria do registro do controle é de pouca utilidade.

    Depois de compilar e registrar seu controle, você deve encontrar as seguintes entradas no 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}

Referências

SDK do Cliente da Internet – Desenvolvimento de Componentes – Inicialização segura e script para controles ActiveX