275 lines
6.1 KiB
C++
275 lines
6.1 KiB
C++
// **************************************************************************
|
|
|
|
// Copyright (c) Microsoft Corporation, All Rights Reserved
|
|
//
|
|
// File: OnTemp.cpp
|
|
//
|
|
// Description:
|
|
// This file implements the register/unregister of temporary
|
|
// event consumers.
|
|
//
|
|
// History:
|
|
//
|
|
// **************************************************************************
|
|
#include "stdafx.h"
|
|
#include "AdvClientDlg.h"
|
|
|
|
BOOL CAdvClientDlg::OnTempRegister()
|
|
{
|
|
HRESULT hr;
|
|
|
|
if(EnsureOfficeNamespace())
|
|
{
|
|
|
|
//create a thread that would call ExecNotificationQuery() semi-synchronously and
|
|
//poll for events
|
|
|
|
|
|
hr = CoMarshalInterThreadInterfaceInStream(IID_IWbemServices,
|
|
m_pOfficeService,
|
|
&m_pStream);
|
|
if (FAILED(hr))
|
|
{
|
|
m_eventList.AddString(_T("Failed to marshal IWbemServices pointer"));
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
m_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc,
|
|
(void *)this, 0, &m_threadId);
|
|
|
|
if (m_thread == NULL)
|
|
{
|
|
m_eventList.AddString(_T("Failed to create event polling thread"));
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void CAdvClientDlg::OnTempUnregister()
|
|
{
|
|
|
|
if(EnsureOfficeNamespace())
|
|
{
|
|
StopThread();
|
|
|
|
m_eventList.ResetContent();
|
|
m_eventList.AddString(_T("unregistered"));
|
|
|
|
|
|
}
|
|
}
|
|
|
|
void CAdvClientDlg::StopThread()
|
|
{
|
|
EnterCriticalSection(&m_critSect);
|
|
|
|
if (m_thread != NULL)
|
|
{
|
|
//m_threadCmd = CT_EXIT;
|
|
SetEvent(m_stopThread);
|
|
WaitForSingleObject(m_ptrReady, 100);
|
|
|
|
CloseHandle(m_thread);
|
|
|
|
m_thread = NULL;
|
|
}
|
|
LeaveCriticalSection(&m_critSect);
|
|
}
|
|
|
|
// ========================================================
|
|
|
|
DWORD WINAPI CAdvClientDlg::ThreadProc(LPVOID lpParameter)
|
|
{
|
|
|
|
CoInitialize(NULL);
|
|
|
|
CAdvClientDlg * pThis = (CAdvClientDlg *)lpParameter;
|
|
|
|
BSTR qLang = SysAllocString(L"WQL");
|
|
if (!qLang)
|
|
{
|
|
(pThis->m_eventList).AddString(_T("SysAllocString failed"));
|
|
SetEvent(pThis->m_ptrReady);
|
|
return 1;
|
|
}
|
|
BSTR query = SysAllocString(L"select * from __InstanceCreationEvent where TargetInstance isa \"SAMPLE_OfficeEquipment\"");
|
|
if (!query)
|
|
{
|
|
(pThis->m_eventList).AddString(_T("SysAllocString failed"));
|
|
SetEvent(pThis->m_ptrReady);
|
|
SysFreeString(qLang);
|
|
return 1;
|
|
}
|
|
|
|
|
|
IWbemServices * pServices = NULL;
|
|
(pThis->m_eventList).ResetContent();
|
|
|
|
HRESULT hr = CoGetInterfaceAndReleaseStream(pThis->m_pStream,
|
|
IID_IWbemServices,
|
|
(void**)&pServices);
|
|
if (FAILED(hr))
|
|
{
|
|
(pThis->m_eventList).AddString(_T("Failed to unmarshal interface: "));
|
|
(pThis->m_eventList).AddString(ErrorString(hr));
|
|
SetEvent(pThis->m_ptrReady);
|
|
return 1;
|
|
}
|
|
|
|
|
|
(pThis->m_eventList).ResetContent();
|
|
|
|
IEnumWbemClassObject * pEnumEvents = NULL;
|
|
|
|
// execute the query.
|
|
hr = pServices->ExecNotificationQuery(qLang, query,
|
|
WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
|
|
NULL, &pEnumEvents);
|
|
|
|
SysFreeString(qLang);
|
|
SysFreeString(query);
|
|
|
|
if(hr == WBEM_S_NO_ERROR)
|
|
{
|
|
TRACE(_T("Executed event query\n"));
|
|
(pThis->m_eventList).AddString(_T("Ready for events"));
|
|
|
|
while(WaitForSingleObject((pThis->m_stopThread), 10) != WAIT_OBJECT_0)
|
|
{
|
|
IWbemClassObject * pEvent = NULL;
|
|
ULONG uReturned = 0;
|
|
|
|
//poll for an event
|
|
hr = pEnumEvents->Next(100,
|
|
1,
|
|
&pEvent,
|
|
&uReturned);
|
|
if (SUCCEEDED(hr) && uReturned > 0)
|
|
{
|
|
DisplayEvents(pThis, 1, &pEvent);
|
|
pEvent->Release();
|
|
}
|
|
}
|
|
|
|
//thread terminating:
|
|
pEnumEvents->Release();
|
|
|
|
}
|
|
else
|
|
{
|
|
TRACE(_T("ExecNotificationQuery() failed %s\n"), ErrorString(hr));
|
|
(pThis->m_eventList).AddString(_T("Failed To Register"));
|
|
|
|
} //endif ExecQuery()
|
|
|
|
SetEvent(pThis->m_ptrReady);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
// ========================================================
|
|
STDMETHODIMP CAdvClientDlg::DisplayEvents(CAdvClientDlg *pThis,
|
|
LONG lObjectCount,
|
|
IWbemClassObject **ppObjArray)
|
|
{
|
|
|
|
if (!pThis)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
HRESULT hRes;
|
|
CString clMyBuff;
|
|
BSTR objName = NULL;
|
|
BSTR propName = NULL;
|
|
VARIANT pVal, vDisp;
|
|
IDispatch *pDisp = NULL;
|
|
IWbemClassObject *tgtInst = NULL;
|
|
|
|
VariantInit(&pVal);
|
|
VariantInit(&vDisp);
|
|
|
|
objName = SysAllocString(L"TargetInstance");
|
|
if (!objName)
|
|
return E_OUTOFMEMORY;
|
|
propName = SysAllocString(L"Item");
|
|
if (!propName)
|
|
{
|
|
SysFreeString(objName);
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
// walk though the classObjects...
|
|
for (int i = 0; i < lObjectCount; i++)
|
|
{
|
|
// clear my output buffer.
|
|
clMyBuff.Empty();
|
|
|
|
// get what was added. This will be an embedded object (VT_DISPATCH). All
|
|
// WBEM interfaces are derived from IDispatch.
|
|
if ((hRes = ppObjArray[i]->Get(objName, 0L,
|
|
&vDisp, NULL, NULL)) == S_OK)
|
|
{
|
|
//--------------------------------
|
|
// pull the IDispatch out of the various. Dont cast directly to to IWbemClassObject.
|
|
// it MIGHT work now but a suptle change later will break your code. The PROPER
|
|
// way is to go through QueryInterface and do all the right Release()'s.
|
|
pDisp = (IDispatch *)V_DISPATCH(&vDisp);
|
|
|
|
//--------------------------------
|
|
// ask for the IWbemClassObject which is the embedded object. This will be the
|
|
// instance that was created.
|
|
if(SUCCEEDED(pDisp->QueryInterface(IID_IWbemClassObject, (void **)&tgtInst)))
|
|
{
|
|
//--------------------------------
|
|
// dont need the IDispatch anymore.
|
|
pDisp->Release();
|
|
|
|
//--------------------------------
|
|
// get the 'Item' property out of the embedded object.
|
|
if ((hRes = tgtInst->Get(propName, 0L,
|
|
&pVal, NULL, NULL)) == S_OK)
|
|
{
|
|
//--------------------------------
|
|
// done with it.
|
|
tgtInst->Release();
|
|
|
|
// compose a string for the listbox.
|
|
clMyBuff = _T("SAMPLE_OfficeEquipment Instance added for: ");
|
|
clMyBuff += V_BSTR(&pVal);
|
|
|
|
// output the buffer.
|
|
(pThis->m_eventList).AddString(clMyBuff);
|
|
}
|
|
else
|
|
{
|
|
TRACE(_T("Get() Item failed %s\n"), ErrorString(hRes));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TRACE(_T("QI() failed \n"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TRACE(_T("Get() targetInst failed %s\n"), ErrorString(hRes));
|
|
(pThis->m_eventList).AddString(_T("programming error"));
|
|
} //endif Get()
|
|
|
|
} // endfor
|
|
|
|
SysFreeString(propName);
|
|
SysFreeString(objName);
|
|
VariantClear(&pVal);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|