Пометить элементы ActiveX MFC как безопасные для сценариев и инициализации

В этой статье описывается, как пометить элементы activeX MFC как безопасные для сценариев и инициализации.

Исходная версия продукта: Элементы activeX MFC
Исходный номер базы знаний: 161873

Сводка

По умолчанию элементы управления ActiveX MFC не помечаются как безопасные для сценариев и безопасные для инициализации. Это становится очевидным, когда элемент управления выполняется в Интернете Обозреватель с уровнем безопасности, равным среднему или высокому. В любом из этих режимов могут отображаться предупреждения о том, что данные элемента управления небезопасны или что элемент управления может быть небезопасн для использования скриптами.

Для устранения этих ошибок элемент управления может использовать два метода. Первый включает элемент управления, реализующий IObjectSafety интерфейс, и полезен для элементов управления, которые хотели бы изменить свое поведение и стать безопасным при выполнении в контексте браузера. Второй включает изменение функции элемента управления DllRegisterServer , чтобы пометить элемент управления безопасным в реестре. В этой статье рассматривается второй из этих методов. Первый метод, реализуя IObjectSafety интерфейс, рассматривается в пакете SDK для интернет-клиента.

Имейте в виду, что элемент управления должен быть помечен как безопасный только в том случае, если он действительно безопасен. Описание см. в документации по пакету SDK для интернет-клиента. См. раздел Безопасная инициализация и скрипты для элементов ActiveX в разделе Разработка компонентов.

Примечание.

В этой статье не рассматривается, как пометить элемент управления безопасным для скачивания. Дополнительные сведения о скачивании кода и подписывание кода см. в разделе Пакет SDK для интернет-клиента.

Дополнительная информация

Выполните следующие действия, чтобы пометить элемент управления ActiveX MFC как безопасный для сценариев и безопасный для инициализации.

  1. Реализуйте вспомогательные CreateComponentCategory функции и RegisterCLSIDInCategory , добавив в проект следующие файлы cathelp.h и cathelp.cpp.

    • 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. Измените , DllRegisterServer чтобы пометить элемент управления как безопасный. Найдите реализацию DllRegisterServer в файле .cpp проекта. Вам потребуется добавить несколько элементов в этот .cpp файл. Добавьте файл, реализующий CreateComponentCategory и RegisterCLSIDInCategory:

    #include "CatHelp.h"
    

    Определите ИДЕНТИФИКАТОР GUID, связанный с категориями компонентов безопасности:

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

    Определите GUID, связанный с элементом управления. Для простоты можно заимствовать GUID из IMPLEMENT_OLECREATE_EX макроса в файле main .cpp для элемента управления . Немного измените формат, чтобы он выглядел следующим образом:

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

    Чтобы пометить элемент управления как безопасный для сценариев и инициализации, измените функцию 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);
    
        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;
    }
    

    Обычно вы не изменяете функцию DllUnregisterServer по следующим двум причинам:

    • Вы не хотите удалять категорию компонентов, так как ее могут использовать другие элементы управления.

    • Хотя определена UnRegisterCLSIDInCategory функция, по умолчанию DllUnregisterServer запись элемента управления полностью удаляется из реестра. Таким образом, удаление категории из регистрации элемента управления бесполезно.

    После компиляции и регистрации элемента управления в реестре должны находиться следующие записи:

    • 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}

Ссылки

Пакет SDK для интернет-клиента — разработка компонентов— безопасная инициализация и скрипты для элементов ActiveX