Markera MFC ActiveX-kontroller som säkra för skript och initiering

Den här artikeln beskriver hur du markerar MFC ActiveX-kontroller som säkra för skript och initiering.

Ursprunglig produktversion: MFC ActiveX-kontroller
Ursprungligt KB-nummer: 161873

Sammanfattning

Som standard är MFC ActiveX-kontroller inte markerade som säkra för skript och säkra för initiering. Detta blir tydligt när kontrollen körs i Internet Explorer med säkerhetsnivån inställd på medel eller hög. I något av dessa lägen kan varningar visas om att kontrollens data inte är säkra eller att kontrollen kanske inte är säker för skript att använda.

Det finns två metoder som en kontroll kan använda för att eliminera dessa fel. Den första omfattar kontrollen som implementerar IObjectSafety gränssnittet och är användbar för kontroller som vill ändra sitt beteende och bli säkra om de körs i kontexten för en webbläsare. Den andra innebär att ändra kontrollens DllRegisterServer funktion för att markera kontrollen som säker i registret. Den här artikeln beskriver den andra av dessa metoder. Den första metoden, som implementerar IObjectSafety gränssnittet, beskrivs i Internet Client SDK.

Tänk på att en kontroll endast ska markeras som säker om den i själva verket är säker. En beskrivning av detta finns i dokumentationen för Internet Client SDK. Se Säker initiering och skriptkörning för ActiveX-kontroller under avsnittet Komponentutveckling.

Obs!

Den här artikeln beskriver inte hur du markerar en kontroll säker för nedladdning. Mer information om nedladdning av kod och kodsignering finns i Internet Client SDK.

Mer information

Följ dessa steg för att markera din MFC ActiveX-kontroll som säker för skript och säker för initiering:

  1. Implementera hjälpfunktionerna CreateComponentCategory och RegisterCLSIDInCategory genom att lägga till följande cathelp.h- och cathelp.cpp-filer i projektet.

    • 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 Ändra för att markera kontrollen som säker. Leta upp implementeringen av DllRegisterServer i en .cpp fil i projektet. Du måste lägga till flera saker i den här .cpp filen. Inkludera filen som implementerar CreateComponentCategory och RegisterCLSIDInCategory:

    #include "CatHelp.h"
    

    Definiera det GUID som är associerat med säkerhetskomponentkategorierna:

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

    Definiera det GUID som är associerat med din kontroll. För enkelhetens skull kan du låna GUID från makrot IMPLEMENT_OLECREATE_EX i huvudfilen .cpp för kontrollen. Justera formatet något så att det ser ut så här:

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

    Om du vill markera kontrollen som både säker för skript och initiering ändrar du funktionen på DllRegisterServer följande sätt:

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

    Normalt sett ändrar du inte funktionen av DllUnregisterServer följande två skäl:

    • Du vill inte ta bort en komponentkategori eftersom andra kontroller kanske använder den.

    • Även om det finns en UnRegisterCLSIDInCategory definierad funktion tar kontrollens post som standard DllUnregisterServer bort helt från registret. Därför är det inte särskilt bra att ta bort kategorin från kontrollens registrering.

    När du har kompilerats och registrerat kontrollen bör du hitta följande poster i registret:

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

Referenser

Internet Client SDK – Komponentutveckling – Säker initiering och skriptkörning för ActiveX-kontroller