다음을 통해 공유


별도의 프로세스에서 싱크에 대한 보안 낮추기

WMI(Windows Management Instrumentation)는 별도의 프로세스에서 클라이언트 응용 프로그램에 대한 비동기 콜백을 수신하는 싱크를 만들 수 있습니다. 별도의 프로세스는 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(Software Development Kit)의 COM 설명서를 참조하세요.