329 lines
7.6 KiB
C++
329 lines
7.6 KiB
C++
// EventDmp.cpp : Defines the entry point for the console application.
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
|
|
// Args:
|
|
// Namespace
|
|
// Query
|
|
// Timeout
|
|
|
|
void PrintUsage()
|
|
{
|
|
printf(
|
|
"Subscribes to a WMI event query and prints received events.\n"
|
|
"\n"
|
|
"EVENTDMP [/Nnamespace] [/Ttimeout] [/Bfilename] [/M] query\n"
|
|
"\n"
|
|
"/N Namespace to use (root\\default used by default). \n"
|
|
"/T Specifies the number of seconds EVENTDMP should wait to terminate \n"
|
|
" after getting an event. When another event is received the count-\n"
|
|
" down starts over. -1 (the default value) indicates there is no \n"
|
|
" timeout.\n"
|
|
"/B Write _IWmiObject blobs to filename instead of printing MOFs to \n"
|
|
" stdout.\n"
|
|
"/M Perform the query as a monitor query.\n"
|
|
);
|
|
}
|
|
|
|
HANDLE heventReceived;
|
|
|
|
class CObjSink : public IWbemObjectSink
|
|
{
|
|
public:
|
|
CObjSink() :
|
|
m_lRef(0)
|
|
{
|
|
}
|
|
|
|
public:
|
|
STDMETHODIMP QueryInterface(REFIID refid, PVOID *ppThis)
|
|
{
|
|
if (refid == IID_IUnknown)
|
|
*ppThis = (IUnknown*) this;
|
|
else if (refid == IID_IWbemObjectSink)
|
|
*ppThis = (IWbemObjectSink*) this;
|
|
else
|
|
return E_NOINTERFACE;
|
|
|
|
AddRef();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) AddRef(void)
|
|
{
|
|
return InterlockedIncrement(&m_lRef);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) Release(void)
|
|
{
|
|
LONG lRet = InterlockedDecrement(&m_lRef);
|
|
|
|
if (lRet == 0)
|
|
delete this;
|
|
|
|
return lRet;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE SetStatus(
|
|
LONG lFlags,
|
|
HRESULT hResult,
|
|
BSTR strParam,
|
|
IWbemClassObject *pObjParam);
|
|
|
|
protected:
|
|
LONG m_lRef;
|
|
};
|
|
|
|
class CMofSink : public CObjSink
|
|
{
|
|
public:
|
|
// IWbemObjectSink
|
|
HRESULT STDMETHODCALLTYPE Indicate(
|
|
LONG lObjectCount,
|
|
IWbemClassObject **ppObjArray);
|
|
};
|
|
|
|
#define MAX_OBJ_SIZE 32000
|
|
|
|
class CBinSink : public CObjSink
|
|
{
|
|
public:
|
|
CBinSink() :
|
|
m_pFile(NULL)
|
|
{
|
|
}
|
|
|
|
BOOL Init(LPSTR szFilename)
|
|
{
|
|
m_pFile = fopen(szFilename, "wb");
|
|
|
|
return m_pFile != NULL;
|
|
}
|
|
|
|
~CBinSink()
|
|
{
|
|
if (m_pFile)
|
|
fclose(m_pFile);
|
|
}
|
|
|
|
public:
|
|
// IWbemObjectSink
|
|
HRESULT STDMETHODCALLTYPE Indicate(
|
|
LONG lObjectCount,
|
|
IWbemClassObject **ppObjArray);
|
|
|
|
protected:
|
|
FILE *m_pFile;
|
|
BYTE m_pBuffer[MAX_OBJ_SIZE];
|
|
};
|
|
|
|
int __cdecl main(int argc, char* argv[])
|
|
{
|
|
IWbemLocator *pLocator = NULL;
|
|
DWORD dwTimeout = INFINITE;
|
|
LPSTR szNamespace = "root\\default",
|
|
szBinFilename = NULL,
|
|
szQuery = NULL;
|
|
DWORD dwFlags = 0;
|
|
|
|
for (int i = 1; i < argc; i++)
|
|
{
|
|
LPSTR szArg = argv[i];
|
|
|
|
if (szArg[0] == '/' || szArg[0] == '-')
|
|
{
|
|
switch(toupper(szArg[1]))
|
|
{
|
|
case 'N':
|
|
szNamespace = &szArg[2];
|
|
break;
|
|
|
|
case 'B':
|
|
szBinFilename = &szArg[2];
|
|
break;
|
|
|
|
case 'T':
|
|
dwTimeout = atoi(&szArg[2]) * 1000;
|
|
break;
|
|
|
|
case 'M':
|
|
dwFlags = WBEM_FLAG_MONITOR;
|
|
break;
|
|
|
|
default:
|
|
PrintUsage();
|
|
return 1;
|
|
}
|
|
}
|
|
else
|
|
szQuery = szArg;
|
|
}
|
|
|
|
if (!szQuery)
|
|
{
|
|
PrintUsage();
|
|
return 1;
|
|
}
|
|
|
|
|
|
HRESULT hr;
|
|
|
|
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
|
|
|
if ((hr = CoCreateInstance(
|
|
CLSID_WbemLocator,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IWbemLocator,
|
|
(LPVOID *) &pLocator)) == S_OK)
|
|
{
|
|
IWbemServices *pNamespace = NULL;
|
|
_bstr_t strNamespace = szNamespace;
|
|
|
|
if ((hr = pLocator->ConnectServer(
|
|
strNamespace,
|
|
NULL, // username
|
|
NULL, // password
|
|
NULL, // locale
|
|
0L, // securityFlags
|
|
NULL, // authority (domain for NTLM)
|
|
NULL, // context
|
|
&pNamespace)) == S_OK)
|
|
{
|
|
_bstr_t strWQL = L"WQL",
|
|
strQuery = szQuery;
|
|
CObjSink *pSink;
|
|
|
|
pLocator->Release();
|
|
|
|
if (!szBinFilename)
|
|
pSink = new CMofSink;
|
|
else
|
|
{
|
|
CBinSink *pBinSink = new CBinSink;
|
|
|
|
if (pBinSink->Init(szBinFilename))
|
|
pSink = pBinSink;
|
|
else
|
|
{
|
|
printf("Unable to open '%s'.\n", szBinFilename);
|
|
pNamespace->Release();
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
heventReceived = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
|
|
if (SUCCEEDED(hr =
|
|
pNamespace->ExecNotificationQueryAsync(
|
|
strWQL,
|
|
strQuery,
|
|
dwFlags,
|
|
NULL,
|
|
pSink)))
|
|
{
|
|
while (WaitForSingleObject(heventReceived, dwTimeout) != WAIT_TIMEOUT)
|
|
{
|
|
}
|
|
|
|
pNamespace->CancelAsyncCall(pSink);
|
|
}
|
|
else
|
|
printf("ExecNotificationQueryAsync failed: 0x%X\n", hr);
|
|
|
|
pNamespace->Release();
|
|
|
|
CloseHandle(heventReceived);
|
|
}
|
|
else
|
|
{
|
|
printf("IWbemLocator::ConnectServer failed: 0x%X\n", hr);
|
|
|
|
pLocator->Release();
|
|
}
|
|
}
|
|
else
|
|
printf("CoCreateInstance for CLSID_WbemLocator failed: 0x%X\n", hr);
|
|
|
|
CoUninitialize();
|
|
|
|
return 0;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMofSink::Indicate(
|
|
LONG nEvents,
|
|
IWbemClassObject **ppEvents)
|
|
{
|
|
// Stop us from timing out.
|
|
SetEvent(heventReceived);
|
|
|
|
for (int i = 0; i < nEvents; i++)
|
|
{
|
|
BSTR bstrObj = NULL;
|
|
HRESULT hr;
|
|
|
|
if (SUCCEEDED(hr = ppEvents[i]->GetObjectText(0, &bstrObj)))
|
|
{
|
|
printf("%S", bstrObj);
|
|
|
|
SysFreeString(bstrObj);
|
|
}
|
|
else
|
|
printf(
|
|
"\n// IWbemClassObject::GetObjectText failed : 0x%X\n", hr);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBinSink::Indicate(
|
|
LONG nEvents,
|
|
IWbemClassObject **ppEvents)
|
|
{
|
|
// Stop us from timing out.
|
|
SetEvent(heventReceived);
|
|
|
|
for (int i = 0; i < nEvents; i++)
|
|
{
|
|
HRESULT hr;
|
|
_IWmiObject *pObj = NULL;
|
|
|
|
if (SUCCEEDED(hr = ppEvents[i]->QueryInterface(
|
|
IID__IWmiObject, (LPVOID*) &pObj)))
|
|
{
|
|
DWORD dwRead;
|
|
|
|
hr =
|
|
pObj->GetObjectParts(
|
|
m_pBuffer,
|
|
MAX_OBJ_SIZE,
|
|
WBEM_OBJ_DECORATION_PART | WBEM_OBJ_INSTANCE_PART |
|
|
WBEM_OBJ_CLASS_PART,
|
|
&dwRead);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
fwrite(&dwRead, 1, sizeof(dwRead), m_pFile);
|
|
fwrite(m_pBuffer, 1, dwRead, m_pFile);
|
|
}
|
|
|
|
pObj->Release();
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CObjSink::SetStatus(
|
|
LONG lFlags,
|
|
HRESULT hResult,
|
|
BSTR strParam,
|
|
IWbemClassObject *pObjParam)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
|