將 MFC ActiveX 控制項標示為腳本和初始化的安全

本文說明如何將 MFC ActiveX 控制項標示為可在腳本和初始化時安全地標示。

原始產品版本:   MFC ActiveX 控制項
原始 KB 編號:   161873

摘要

依預設,MFC ActiveX 控制項不會標示為可在腳本中安全,也不會標示為可安全初始化。 當控制項是在 Internet Explorer 中執行時,安全性層級設為 [中] 或 [高] 時,會變得明顯。 在這兩種模式中,警告可能會顯示控制項的資料不安全,或是控制項可能不會安全地使用的腳本。

控制項可使用兩種方法來消除這些錯誤。 第一個功能包含實現介面的控制項 IObjectSafety ,在網際網路瀏覽器的內容中執行時,想要變更其行為並變得安全的控制項十分有用。 第二個套裝程式含修改控制項的 DllRegisterServer 函數,將登錄中的控制項安全標示。 本文涵蓋這些方法的第二個。 第一個方法(實現 IObjectSafety 介面)涵蓋在網際網路用戶端 SDK 中。

請記住,控制項應該只會標示為安全(事實上是安全的)。 請參閱網際網路用戶端 SDK 檔,以取得這項的描述。 請參閱元件開發區段中 ActiveX 控制項的安全初始化和腳本

注意

本文並未涵蓋如何將控制項標記為可安全地下載。 如需有關代碼下載和程式碼簽署的詳細資訊,請參閱網際網路用戶端 SDK。

其他資訊

請遵循下列步驟,將 MFC ActiveX 控制項標示為可安全執行腳本和初始化的安全:

  1. CreateComponentCategory RegisterCLSIDInCategory 將下列的 cathelp 和 cathelp .cpp 檔新增至您的專案,以實現及 helper 函數。

    • Cathelp

      #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

      #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。 為簡潔起見,您可以從 IMPLEMENT_OLECREATE_EX 控制項的主 .cpp 檔案中的宏借用 GUID。 請稍微調整格式,使它看起來如下:

    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 控制項