Partager via


Réduction de la sécurité d’un récepteur dans un processus distinct

Windows Management Instrumentation (WMI) peut créer le récepteur pour recevoir des rappels asynchrones pour une application cliente dans un processus distinct. Le processus distinct est Unsecapp.exe. Utilisez l’interface IWbemUnsecuredApartment. IWbemUnsecuredApartment vous permet de contrôler si Unsecapp.exe authentifie les rappels auprès du récepteur. Pour plus d’informations, voir Définition de la sécurité sur un appel asynchrone.

Vous pouvez ensuite réduire la sécurité de ce processus et WMI peut accéder au récepteur sans restriction. Pour faciliter l’utilisation de cette technique, WMI fournit le processus Unsecapp.exe pour fonctionner en tant que processus distinct. Vous pouvez héberger Unsecapp.exe avec un appel à l’interface IUnsecuredApartment.

L’interface IUnsecuredApartment permet à une application cliente de créer un processus dédié distinct exécutant Unsecapp.exe pour héberger une implémentation IWbemObjectSink. Le processus dédié peut appeler CoInitializeSecurity pour accorder à WMI l’accès au processus dédié sans compromettre la sécurité du processus principal. Après l’initialisation, le processus dédié joue le rôle d’intermédiaire entre le processus principal et WMI.

La procédure suivante décrit comment effectuer un appel asynchrone avec IUnsecuredApartment.

Pour effectuer un appel asynchrone avec IUnsecuredApartment

  1. Créez un processus dédié avec un appel à CoCreateInstance.

    L’exemple de code suivant appelle CoCreateInstance pour créer un processus dédié.

    IUnsecuredApartment* pUnsecApp = NULL;
    
    CoCreateInstance(CLSID_UnsecuredApartment, NULL, 
      CLSCTX_LOCAL_SERVER, IID_IUnsecuredApartment, 
      (void**)&pUnsecApp);
    
  2. Instanciation de l’objet récepteur.

    L'exemple de code suivant crée un nouvel objet récepteur.

    CMySink* pSink = new CMySink;
    pSink->AddRef();
    
  3. Créez un stub pour le récepteur.

    Un stub est une fonction wrapper produite à partir du récepteur.

    L’exemple de code suivant appelle CreateObjectStub pour créer un stub pour le récepteur.

    IUnknown* pStubUnk = NULL; 
    pUnsecApp->CreateObjectStub(pSink, &pStubUnk);
    
  4. Appelez QueryInterface pour le wrapper et demandez un pointeur vers l’interface IWbemObjectSink.

    L’exemple de code suivant appelle QueryInterface et demande un pointeur vers l’interface IWbemObjectSink.

    IWbemObjectSink* pStubSink = NULL;
    pStubUnk->QueryInterface(IID_IWbemObjectSink, (void **)&pStubSink); pStubUnk->Release();
    
  5. Relâchez le pointeur d’objet récepteur.

    Vous pouvez libérer le pointeur d’objet, car le stub est maintenant propriétaire du pointeur.

    L’exemple de code suivant libère le pointeur d’objet récepteur.

    pSink->Release();
    
  6. Utilisez le stub dans tout appel asynchrone.

    Une fois l’appel terminé, relâchez le nombre de références locales.

    L’exemple de code suivant utilise le stub dans un appel asynchrone.

    // pServices is an IWbemServices* object
    pServices->CreateInstanceEnumAsync(strClassName, 0, NULL, pStubSink);
    

    Parfois, vous devrez peut-être annuler un appel asynchrone après avoir passé l’appel. Si vous devez annuler l’appel, annulez l’appel avec le pointeur qui a initialement effectué l’appel.

    L’exemple de code suivant montre comment annuler un appel asynchrone.

    pServices->CancelAsyncCall(pStubSink);
    
  7. Libérez le nombre de références locales lorsque vous avez terminé d’utiliser l’appel asynchrone.

    Veillez à libérer le pointeur pStubSink uniquement après avoir confirmé que l’appel asynchrone n’a pas besoin d’être annulé. En outre, ne relâchez pas pStubSink après que WMI a libéré le pointeur du récepteur pSink. La libération de pStubSink après pSink crée un nombre de références circulaire dans lequel le récepteur et le stub restent en mémoire pour toujours. Au lieu de cela, un emplacement possible pour libérer le pointeur se trouve dans l’appel IWbemObjectSink::SetStatus, effectué par WMI pour signaler que l’appel asynchrone d’origine est terminé.

  8. Lorsque vous avez terminé, annulez l’initialisation de COM avec un appel à Release().

    L’exemple de code suivant montre comment appeler Release() sur le pointeur pUnsecApp.

    pUnsecApp->Release();
    

    Les exemples de code de cette rubrique nécessitent la référence et l’instruction #include suivantes pour être compilés correctement.

    #include <wbemidl.h>
    #pragma comment(lib, "wbemuuid.lib")
    

Pour plus d’informations sur la fonction et les paramètres CoInitializeSecurity, consultez la documentation COM dans le Kit de développement logiciel (SDK) de la plateforme.