Compartilhar via


Reduzir a segurança de um coletor em um processo separado

A WMI (Instrumentação de Gerenciamento do Windows) pode criar o coletor para receber retornos de chamada assíncronos de um aplicativo cliente em um processo separado. O processo separado é o Unsecapp.exe. Use a interface IWbemUnsecuredApartment. A IWbemUnsecuredApartment permite controlar se o Unsecapp.exe autentica retornos de chamada no coletor. Para obter mais informações, confira Configurar a segurança em uma chamada assíncrona.

Em seguida, você pode reduzir a segurança nesse processo e o WMI pode acessar o coletor sem restrições. Para ajudar com essa técnica, o WMI fornece o processo Unsecapp.exe para funcionar como processo separado. Você pode hospedar o Unsecapp.exe com uma chamada para a interface IUnsecuredApartment.

A interface IUnsecuredApartment permite que um aplicativo cliente crie um processo dedicado separado executando o Unsecapp.exe para hospedar uma implementação da IWbemObjectSink. O processo dedicado pode chamar CoInitializeSecurity para conceder ao WMI acesso ao processo dedicado sem comprometer a segurança do processo principal. Após a inicialização, o processo dedicado atua como um intermediário entre o processo principal e o WMI.

O procedimento a seguir descreve como executar uma chamada assíncrona com IUnsecuredApartment.

Para executar uma chamada assíncrona com IUnsecuredApartment

  1. Crie um processo dedicado com uma chamada para CoCreateInstance.

    O exemplo de código a seguir chama CoCreateInstance para criar um processo dedicado.

    IUnsecuredApartment* pUnsecApp = NULL;
    
    CoCreateInstance(CLSID_UnsecuredApartment, NULL, 
      CLSCTX_LOCAL_SERVER, IID_IUnsecuredApartment, 
      (void**)&pUnsecApp);
    
  2. Instancie o objeto de coletor.

    O exemplo de código a seguir cria um novo objeto de coletor.

    CMySink* pSink = new CMySink;
    pSink->AddRef();
    
  3. Crie um stub para o coletor.

    Um stub é uma função de encapsulamento produzida do coletor.

    O exemplo de código a seguir chama CreateObjectStub para criar um stub para o coletor.

    IUnknown* pStubUnk = NULL; 
    pUnsecApp->CreateObjectStub(pSink, &pStubUnk);
    
  4. Chame QueryInterface para o wrapper e solicite um ponteiro para a interface IWbemObjectSink.

    O exemplo de código a seguir chama QueryInterface e solicita um ponteiro para a interface IWbemObjectSink.

    IWbemObjectSink* pStubSink = NULL;
    pStubUnk->QueryInterface(IID_IWbemObjectSink, (void **)&pStubSink); pStubUnk->Release();
    
  5. Solte o ponteiro do objeto coletor.

    Você pode liberar o ponteiro do objeto porque o stub agora é proprietário do ponteiro.

    O exemplo de código a seguir libera o ponteiro do objeto coletor.

    pSink->Release();
    
  6. Use o stub em qualquer chamada assíncrona.

    Quando terminar a chamada, libere a contagem de referência local.

    O exemplo de código a seguir usa o stub em uma chamada assíncrona.

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

    Às vezes, pode ser necessário cancelar uma chamada assíncrona depois de fazer a chamada. Se você precisar cancelar a chamada, cancele-a com o mesmo ponteiro que originalmente fez a chamada.

    O seguinte exemplo de código mostra como cancelar uma chamada assíncrona.

    pServices->CancelAsyncCall(pStubSink);
    
  7. Libere a contagem de referência local quando terminar de usar a chamada assíncrona.

    Libere o ponteiro pStubSink somente depois de confirmar que a chamada assíncrona não precisa ser cancelada. Além disso, não libere o pStubSink depois que o WMI liberar o ponteiro do coletor pSink. A liberação de pStubSink após pSink cria uma contagem de referência circular na qual o coletor e o stub permanecem na memória para sempre. Em vez disso, um possível local para liberar o ponteiro é na chamada IWbemObjectSink::SetStatus, feita pelo WMI para informar que a chamada assíncrona original está concluída.

  8. Quando terminar, não inicialize o COM usando uma chamada para Release().

    O exemplo de código a seguir mostra como chamar Release() no ponteiro pUnsecApp.

    pUnsecApp->Release();
    

    Os exemplos de código neste tópico exigem a seguinte referência e a instrução #include para compilar corretamente.

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

Para obter mais informações sobre a função e os parâmetros CoInitializeSecurity, consulte a documentação do COM no SDK (Software Development Kit) da plataforma.