Снижение безопасности для приемника в отдельном процессе
Инструментарий управления Windows (WMI) может создать приемник для получения асинхронных обратных вызовов для клиентского приложения в отдельном процессе. Отдельный процесс Unsecapp.exe. Используйте интерфейс IWbemUnsecuredApartment . IWbemUnsecuredApartment позволяет управлять проверкой подлинности Unsecapp.exe обратных вызовов в приемник. Дополнительные сведения см. в разделе Настройка безопасности при асинхронном вызове.
Затем вы можете снизить уровень безопасности этого процесса, и WMI сможет получить доступ к приемнику без ограничений. Для поддержки этого метода WMI предоставляет Unsecapp.exe процесс, который будет функционировать как отдельный процесс. Вы можете разместить Unsecapp.exe с помощью вызова интерфейса IUnsecuredApartment .
Интерфейс IUnsecuredApartment позволяет клиентскому приложению создать отдельный выделенный процесс, выполняющийся Unsecapp.exe для размещения реализации IWbemObjectSink . Выделенный процесс может вызывать CoInitializeSecurity, чтобы предоставить WMI-доступ к выделенному процессу без ущерба для безопасности процесса main. После инициализации выделенный процесс выступает в качестве посредника между процессом main и WMI.
В следующей процедуре описывается выполнение асинхронного вызова с помощью IUnsecuredApartment.
Выполнение асинхронного вызова с помощью IUnsecuredApartment
Создайте выделенный процесс с вызовом CoCreateInstance.
Следующий пример кода вызывает CoCreateInstance для создания выделенного процесса.
IUnsecuredApartment* pUnsecApp = NULL; CoCreateInstance(CLSID_UnsecuredApartment, NULL, CLSCTX_LOCAL_SERVER, IID_IUnsecuredApartment, (void**)&pUnsecApp);
Создайте экземпляр объекта приемника.
В следующем примере кода создается новый объект приемника.
CMySink* pSink = new CMySink; pSink->AddRef();
Создайте заглушку для приемника.
Заглушка — это функция-оболочка, созданная из приемника.
В следующем примере кода вызывается метод CreateObjectStub для создания заглушки для приемника.
IUnknown* pStubUnk = NULL; pUnsecApp->CreateObjectStub(pSink, &pStubUnk);
Вызовите QueryInterface для оболочки и запросите указатель на интерфейс IWbemObjectSink .
В следующем примере кода вызывается QueryInterface и запрашивается указатель на интерфейс IWbemObjectSink .
IWbemObjectSink* pStubSink = NULL; pStubUnk->QueryInterface(IID_IWbemObjectSink, (void **)&pStubSink); pStubUnk->Release();
Отпустите указатель на объект приемника.
Вы можете освободить указатель объекта, так как заглушка теперь владеет указателем.
В следующем примере кода освобождается указатель объекта приемника.
pSink->Release();
Используйте заглушку в любом асинхронном вызове.
Завершив вызов, отпустите число локальных ссылок.
В следующем примере кода используется заглушка в асинхронном вызове.
// pServices is an IWbemServices* object pServices->CreateInstanceEnumAsync(strClassName, 0, NULL, pStubSink);
Иногда после выполнения вызова может потребоваться отменить асинхронный вызов. Если необходимо отменить вызов, отмените вызов с помощью того же указателя, который был выполнен изначально.
В следующем примере кода показано, как отменить асинхронный вызов.
pServices->CancelAsyncCall(pStubSink);
Освободит число локальных ссылок после завершения асинхронного вызова.
Отпустите указатель pStubSink только после подтверждения отмены асинхронного вызова. Кроме того, не отпускайте pStubSink после того, как WMI освобождает указатель приемника pSink . При освобождении pStubSink после pSink создается циклическое число ссылок, в котором приемник и заглушка остаются в памяти навсегда. Вместо этого возможное расположение для освобождения указателя находится в вызове IWbemObjectSink::SetStatus , выполненном WMI, чтобы сообщить о завершении исходного асинхронного вызова.
По завершении не инициализируйте COM с помощью вызова Release().
В следующем примере кода показано, как вызвать Release() в указателе pUnsecApp .
pUnsecApp->Release();
Для правильной компиляции примеров кода в этом разделе требуется следующая ссылка и оператор #include.
#include <wbemidl.h> #pragma comment(lib, "wbemuuid.lib")
Дополнительные сведения о функции и параметрах CoInitializeSecurity см. в документации com в пакете средств разработки программного обеспечения платформы (SDK).