#define _WIN32_DCOM #include <iostream> using namespace std; #include <comdef.h> #include <Wbemidl.h> #include <atlcomcli.h> #pragma comment(lib, "wbemuuid.lib") class EventSink : public IWbemObjectSink { LONG m_lRef; bool bDone; public: EventSink() { m_lRef = 0; } ~EventSink() { bDone = true; } virtual ULONG STDMETHODCALLTYPE AddRef() { return InterlockedIncrement(&m_lRef); } virtual ULONG STDMETHODCALLTYPE Release() { LONG lRef = InterlockedDecrement(&m_lRef); if(lRef == 0) delete this; return lRef; } virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv) { if (riid == IID_IUnknown || riid == IID_IWbemObjectSink) { *ppv = (IWbemObjectSink *) this; AddRef(); return WBEM_S_NO_ERROR; } else return E_NOINTERFACE; } virtual HRESULT STDMETHODCALLTYPE Indicate( LONG lObjectCount, IWbemClassObject __RPC_FAR *__RPC_FAR *apObjArray ) { HRESULT hres = S_OK; for (int i = 0; i < lObjectCount; i++) { IWbemClassObject *pObj = apObjArray[i]; _variant_t vtProp; // Get the value of the Name property // ->GetNames(); //HRESULT hr = pObj->Get(L"Name", 0, &vtProp, 0, 0); HRESULT hr = pObj->Get(_bstr_t(L"TargetInstance"), 0, &vtProp, 0, 0); if (!FAILED(hr)) { IUnknown* str = vtProp; hr = str->QueryInterface( IID_IWbemClassObject, reinterpret_cast< void** >( &apObjArray[i] ) ); if ( SUCCEEDED( hr ) ) { _variant_t cn; hr = apObjArray[i]->Get( L"Name", 0, &cn, NULL, NULL ); if ( SUCCEEDED( hr ) ) { if ((cn.vt==VT_NULL) || (cn.vt==VT_EMPTY)) std::wcout << "Name : " << ((cn.vt==VT_NULL) ? "NULL" : "EMPTY") << endl; else std::wcout << "Name : " << cn.bstrVal << endl; } VariantClear(&cn); hr = apObjArray[i]->Get( L"ProcessId", 0, &cn, NULL, NULL ); if ( SUCCEEDED( hr ) ) { if ((cn.vt==VT_NULL) || (cn.vt==VT_EMPTY)) std::wcout << "PID : " << ((cn.vt==VT_NULL) ? "NULL" : "EMPTY") << endl; else if ( cn.vt == VT_I4 ) std::wcout << "PID : " << cn.intVal << endl; else std::wcout << "PID : " << cn.bstrVal << endl; } VariantClear(&cn); } } VariantClear(&vtProp); } return WBEM_S_NO_ERROR; } virtual HRESULT STDMETHODCALLTYPE SetStatus( /* [in] */ LONG lFlags, /* [in] */ HRESULT hResult, /* [in] */ BSTR strParam, /* [in] */ IWbemClassObject __RPC_FAR *pObjParam ) { if(lFlags == WBEM_STATUS_COMPLETE) { printf("Call complete. hResult = 0x%X\n", hResult); } else if(lFlags == WBEM_STATUS_PROGRESS) { printf("Call in progress.\n"); } return WBEM_S_NO_ERROR; } }; int _tmain(int argc, _TCHAR* argv[]) { HRESULT hres; // Step 1: -------------------------------------------------- // Initialize COM. ------------------------------------------ hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres)) { cout << "Failed to initialize COM library. Error code = 0x" << hex << hres << endl; return 1; // Program has failed. } // Step 2: -------------------------------------------------- // Set general COM security levels -------------------------- hres = CoInitializeSecurity( NULL, -1, // COM negotiates service NULL, // Authentication services NULL, // Reserved RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation NULL, // Authentication info EOAC_NONE, // Additional capabilities NULL // Reserved ); if (FAILED(hres)) { cout << "Failed to initialize security. Error code = 0x" << hex << hres << endl; CoUninitialize(); return 1; // Program has failed. } // Step 3: --------------------------------------------------- // Obtain the initial locator to WMI ------------------------- IWbemLocator *pLoc = NULL; hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc); if (FAILED(hres)) { cout << "Failed to create IWbemLocator object. " << "Err code = 0x" << hex << hres << endl; CoUninitialize(); return 1; // Program has failed. } // Step 4: --------------------------------------------------- // Connect to WMI through the IWbemLocator::ConnectServer method IWbemServices *pSvc = NULL; // Connect to the local root\cimv2 namespace // and obtain pointer pSvc to make IWbemServices calls. hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc ); if (FAILED(hres)) { cout << "Could not connect. Error code = 0x" << hex << hres << endl; pLoc->Release(); CoUninitialize(); return 1; // Program has failed. } cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl; // Step 5: -------------------------------------------------- // Set security levels on the proxy ------------------------- hres = CoSetProxyBlanket( pSvc, // Indicates the proxy to set RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx NULL, // Server principal name RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx NULL, // client identity EOAC_NONE // proxy capabilities ); if (FAILED(hres)) { cout << "Could not set proxy blanket. Error code = 0x" << hex << hres << endl; pSvc->Release(); pLoc->Release(); CoUninitialize(); return 1; // Program has failed. } // Step 6: ------------------------------------------------- // Receive event notifications ----------------------------- // Use an unsecured apartment for security IUnsecuredApartment* pUnsecApp = NULL; hres = CoCreateInstance(CLSID_UnsecuredApartment, NULL, CLSCTX_LOCAL_SERVER, IID_IUnsecuredApartment, (void**)&pUnsecApp); EventSink* pSink = new EventSink; pSink->AddRef(); IUnknown* pStubUnk = NULL; pUnsecApp->CreateObjectStub(pSink, &pStubUnk); IWbemObjectSink* pStubSink = NULL; pStubUnk->QueryInterface(IID_IWbemObjectSink, (void **) &pStubSink); // The ExecNotificationQueryAsync method will call // The EventQuery::Indicate method when an event occurs hres = pSvc->ExecNotificationQueryAsync( _bstr_t("WQL"), _bstr_t("SELECT * " "FROM __InstanceCreationEvent WITHIN 1 " "WHERE TargetInstance ISA 'Win32_Process'"), WBEM_FLAG_SEND_STATUS, NULL, pStubSink); // Check for errors. if (FAILED(hres)) { printf("ExecNotificationQueryAsync failed " "with = 0x%X\n", hres); pSvc->Release(); pLoc->Release(); pUnsecApp->Release(); pStubUnk->Release(); pSink->Release(); pStubSink->Release(); CoUninitialize(); return 1; } // Wait for the event Sleep(20000); hres = pSvc->CancelAsyncCall(pStubSink); // Cleanup // ======== pSvc->Release(); pLoc->Release(); pUnsecApp->Release(); pStubUnk->Release(); pSink->Release(); pStubSink->Release(); CoUninitialize(); return 0; // Program successfully completed. }
[C++][COM] Notify creating process by WMI
2014. 4. 9. 09:57