Lowering the Security for a Sink in a Separate Process

Windows Management Instrumentation (WMI) can create the sink to receive asynchronous callbacks for a client application in a separate process. The separate process is Unsecapp.exe. Use the IWbemUnsecuredApartment interface. IWbemUnsecuredApartment allows you to control whether Unsecapp.exe authenticates callbacks to the sink. For more information, see Setting Security on an Asynchronous Call.

You can then lower the security on that process and WMI can access the sink without restriction. To assist with this technique WMI provides the Unsecapp.exe process to function as the separate process. You can host Unsecapp.exe with a call to the IUnsecuredApartment interface.

The IUnsecuredApartment interface allows a client application to create a separate dedicated process running Unsecapp.exe for hosting a IWbemObjectSink implementation. The dedicated process can call CoInitializeSecurity to grant WMI access to the dedicated process without compromising the security of the main process. After initialization, the dedicated process acts as an intermediary between the main process and WMI.

The following procedure describes how to perform an asynchronous call with IUnsecuredApartment.

To perform an asynchronous call with IUnsecuredApartment

  1. Create a dedicated process with a call to CoCreateInstance.

    The following code example calls CoCreateInstance to create a dedicated process.

    IUnsecuredApartment* pUnsecApp = NULL;
    
    CoCreateInstance(CLSID_UnsecuredApartment, NULL, 
      CLSCTX_LOCAL_SERVER, IID_IUnsecuredApartment, 
      (void**)&pUnsecApp);
    
  2. Instantiate the sink object.

    The following code example creates a new sink object.

    CMySink* pSink = new CMySink;
    pSink->AddRef();
    
  3. Create a stub for the sink.

    A stub is a wrapper function produced from the sink.

    The following code example calls CreateObjectStub to create a stub for the sink.

    IUnknown* pStubUnk = NULL; 
    pUnsecApp->CreateObjectStub(pSink, &pStubUnk);
    
  4. Call QueryInterface for the wrapper, and request a pointer to the IWbemObjectSink interface.

    The following code example calls QueryInterface and requests a pointer to the IWbemObjectSink interface.

    IWbemObjectSink* pStubSink = NULL;
    pStubUnk->QueryInterface(IID_IWbemObjectSink, (void **)&pStubSink); pStubUnk->Release();
    
  5. Release the sink object pointer.

    You can release the object pointer because the stub now owns the pointer.

    The following code example releases the sink object pointer.

    pSink->Release();
    
  6. Use the stub in any asynchronous call.

    When finished with the call, release the local reference count.

    The following code example uses the stub in an asynchronous call.

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

    At times you may have to cancel an asynchronous call after you make the call. If you need to cancel the call, cancel the call with the same pointer that originally made the call.

    The following code example shows how to cancel an asynchronous call.

    pServices->CancelAsyncCall(pStubSink);
    
  7. Release the local reference count when you are done using the asynchronous call.

    Make sure to release the pStubSink pointer only after you confirm that the asynchronous call does not need to be canceled. Further, do not release pStubSink after WMI releases the pSink sink pointer. Releasing pStubSink after pSink creates a circular reference count in which both the sink and the stub stay in memory forever. Instead, a possible location to release the pointer is in the IWbemObjectSink::SetStatus call, made by WMI to report that the original asynchronous call is complete.

  8. When finished, uninitialize COM with a call to Release().

    The following code example shows how to call Release() on the pUnsecApp pointer.

    pUnsecApp->Release();
    

    The code examples in this topic require the following reference and #include statement to correctly compile.

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

For more information about the CoInitializeSecurity function and parameters, see the COM documentation in the Platform Software Development Kit (SDK).