次の方法で共有


別のプロセスにあるシンクのセキュリティの引き下げ

Windows Management Instrumentation (WMI) は、別のプロセスでクライアント アプリケーションの非同期コールバックを受信するシンクを作成できます。 この別のプロセスは、Unsecapp.exe です。 IWbemUnsecuredApartment インターフェイスを使用します。 IWbemUnsecuredApartment を使用すると、Unsecapp.exe でシンクへのコールバックを認証するかどうかを制御できます。 詳細については、「非同期呼び出しでのセキュリティの設定」を参照してください。

そうすると、そのプロセスのセキュリティを下げることができ、WMI から制限なくシンクにアクセスできます。 この手法を支援するために、WMI は別のプロセスとして機能する Unsecapp.exe プロセスを提供します。 IUnsecuredApartment インターフェイスへの呼び出しを使用して、Unsecapp.exe をホストできます。

IUnsecuredApartment インターフェイスを使用すると、クライアント アプリケーションが IWbemObjectSink 実装をホストするために Unsecapp.exe を実行する別の専用プロセスを作成できます。 専用プロセスでは、CoInitializeSecurity を呼び出して、メイン プロセスのセキュリティを損なうことなく、WMI に専用プロセスへのアクセス権を付与できます。 初期化後、専用プロセスは、メイン プロセスと WMI の間の仲介役として機能します。

次の手順では、IUnsecuredApartment を使用して非同期呼び出しを実行する方法について説明します。

IUnsecuredApartment で非同期呼び出しを実行するには

  1. CoCreateInstance への呼び出しを使用して、専用プロセスを作成します。

    次のコード例では、CoCreateInstance を呼び出して、専用プロセスを作成します。

    IUnsecuredApartment* pUnsecApp = NULL;
    
    CoCreateInstance(CLSID_UnsecuredApartment, NULL, 
      CLSCTX_LOCAL_SERVER, IID_IUnsecuredApartment, 
      (void**)&pUnsecApp);
    
  2. シンク オブジェクトのインスタンスを作成します。

    次のコード例では、新しいシンク オブジェクトを作成します。

    CMySink* pSink = new CMySink;
    pSink->AddRef();
    
  3. シンクに対するスタブを作成します。

    スタブは、シンクから生成されるラッパー関数です。

    次のコード例では、CreateObjectStub を呼び出し、シンクに対するスタブを作成します。

    IUnknown* pStubUnk = NULL; 
    pUnsecApp->CreateObjectStub(pSink, &pStubUnk);
    
  4. ラッパーに対して QueryInterface を呼び出し、IWbemObjectSink インターフェイスへのポインターを要求します。

    次のコード例では、QueryInterface を呼び出し、IWbemObjectSink インターフェイスへのポインターを要求します。

    IWbemObjectSink* pStubSink = NULL;
    pStubUnk->QueryInterface(IID_IWbemObjectSink, (void **)&pStubSink); pStubUnk->Release();
    
  5. シンク オブジェクト ポインターを解放します。

    スタブでポインターを所有するようになったため、オブジェクト ポインターを解放できます。

    次のコード例では、シンク オブジェクト ポインターを解放します。

    pSink->Release();
    
  6. 任意の非同期呼び出しでスタブを使用します。

    呼び出しが完了したら、ローカル参照カウントを解放します。

    次のコード例では、非同期呼び出しでスタブを使用しています。

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

    呼び出し後に非同期呼び出しを取り消す必要がある場合があります。 呼び出しを取り消す必要がある場合は、最初に呼び出しを行ったのと同じポインターを使用して呼び出しをキャンセルします。

    次のコード例では、非同期呼び出しを取り消す方法を示しています。

    pServices->CancelAsyncCall(pStubSink);
    
  7. 非同期呼び出しの使用が完了したら、ローカル参照カウントを解放します。

    非同期呼び出しを取り消す必要がないことを確認した後にのみ、pStubSink ポインターを解放するようにしてください。 また、WMI によって pSink シンク ポインターが解放された後は、pStubSink を解放しないでください。 pSink の後に pStubSink を解放すると、シンクとスタブの両方がメモリに永遠に保持される循環参照カウントが作成されます。 代わりに、ポインターを解放できる場所は、元の非同期呼び出しが完了したことを報告するために WMI によって行われた IWbemObjectSink::SetStatus 呼び出し内です。

  8. 完了したら、Release() への呼び出しを使用して、COM を初期化前の状態に戻します。

    次のコード例は、pUnsecApp ポインターで Release() を呼び出す方法を示しています。

    pUnsecApp->Release();
    

    このトピックのコード例を正しくコンパイルするには、次の参照と #include ステートメントが必要です。

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

CoInitializeSecurity 関数とパラメータの詳細については、プラットフォーム ソフトウェア開発キット (SDK) の COM に関するンドキュメントを参照してください。