2025-04-27 07:49:33 -04:00

548 lines
13 KiB
C++

// TestDlg.cpp : implementation file
//
#include "stdafx.h"
#include "NCETest.h"
#include "TestDlg.h"
#include "NCObjApi.h"
#include "Events.h"
//#include "SecDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
HANDLE g_hConnection;
// g_hConnectionDWORD,
// g_hConnection3Prop,
// g_hConnectionAllProps;
enum EVENT_TYPE
{
EVENT_Generic,
EVENT_Blob,
EVENT_DWORD,
EVENT_3Prop,
EVENT_AllProps
};
enum API_TYPE
{
API_WmiSetAndCommitObject,
API_WmiCommitObject,
API_WmiSetObjectPropWmiCommitObject,
API_WmiSetObjectPropsWmiCommitObject,
API_WmiReportEvent,
API_WmiReportEventBlob,
};
// The first event index that is a real property event.
#define FIRST_PROP_EVENT EVENT_DWORD
/////////////////////////////////////////////////////////////////////////////
// CTestDlg dialog
CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTestDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CTestDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
ZeroMemory(m_pEvents, sizeof(m_pEvents));
}
CTestDlg::~CTestDlg()
{
FreeHandles();
}
#define BUFFER_SIZE 64000
#define SEND_LATENCY 1000
void CTestDlg::Connect()
{
g_hConnection =
WmiEventSourceConnect(
L"root\\cimv2",
L"NCETest Event Provider",
TRUE,
BUFFER_SIZE,
SEND_LATENCY,
this,
EventSourceCallback);
/*
LPCWSTR szQuery = L"select * from MSFT_NCETest_DWORDEvent";
g_hConnectionDWORD =
WmiCreateRestrictedConnection(
g_hConnection,
1,
&szQuery,
this,
EventSourceCallback);
szQuery = L"select * from MSFT_NCETest_3PropEvent";
g_hConnection3Prop =
WmiCreateRestrictedConnection(
g_hConnection,
1,
&szQuery,
this,
EventSourceCallback);
szQuery = L"select * from MSFT_NCETest_AllPropTypesEvent";
g_hConnectionAllProps =
WmiCreateRestrictedConnection(
g_hConnection,
1,
&szQuery,
this,
EventSourceCallback);
*/
if (g_hConnection != NULL)
{
// Setup some events.
m_pEvents[0] = new CGenericEvent;
m_pEvents[1] = new CBlobEvent;
m_pEvents[2] = new CDWORDEvent;
m_pEvents[3] = new CSmallEvent;
m_pEvents[4] = new CAllPropsTypeEvent;
for (int i = 0; i < NUM_EVENT_TYPES; i++)
{
if (!m_pEvents[i]->Init())
{
CString strMsg;
strMsg.Format(
"Unable to init '%s'",
(LPCTSTR) m_pEvents[i]->m_strName);
AfxMessageBox(strMsg);
}
}
}
else
{
CString strMsg;
strMsg.Format(
"WmiEventSourceConnect failed (err = %d)",
GetLastError());
AfxMessageBox(strMsg);
}
}
void CTestDlg::FreeHandles()
{
for (int i = 0; i < NUM_EVENT_TYPES; i++)
{
if (m_pEvents[i])
{
delete m_pEvents[i];
m_pEvents[i] = NULL;
}
}
if (g_hConnection)
{
WmiEventSourceDisconnect(g_hConnection);
g_hConnection = NULL;
}
}
void CTestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTestDlg)
DDX_Control(pDX, IDC_CALLBACK, m_ctlCallback);
DDX_Control(pDX, IDC_API, m_ctlAPI);
DDX_Control(pDX, IDC_EVENT_TYPES, m_ctlEventTypes);
//}}AFX_DATA_MAP
if (!pDX->m_bSaveAndValidate)
{
int nEvents;
nEvents =
theApp.GetProfileInt("Settings", "Events", 1);
if (nEvents <= 0)
nEvents = 1;
SetDlgItemInt(IDC_COUNT, nEvents);
}
else
{
theApp.WriteProfileInt("Settings", "Events", GetDlgItemInt(IDC_COUNT));
theApp.WriteProfileInt("Settings", "API", m_ctlAPI.GetCurSel());
theApp.WriteProfileInt("Settings", "Type", m_ctlEventTypes.GetCurSel());
}
}
BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
//{{AFX_MSG_MAP(CTestDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_CONNECT, OnConnect)
ON_CBN_SELCHANGE(IDC_EVENT_TYPES, OnSelchangeEventTypes)
ON_BN_CLICKED(IDC_SEND, OnSend)
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_COPY, OnCopy)
ON_BN_CLICKED(IDC_CLEAR, OnClear)
ON_BN_CLICKED(IDC_CONNECTION_SD, OnConnectionSd)
ON_BN_CLICKED(IDC_EVENT_SD, OnEventSd)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTestDlg message handlers
BOOL CTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// Save this off for later.
m_hwndStatus = ::GetDlgItem(m_hWnd, IDC_CALLBACK);
// Connect to the non-COM API.
Connect();
// Setup our combo boxes.
for (int i = 0; i < NUM_EVENT_TYPES; i++)
m_ctlEventTypes.AddString(m_pEvents[i]->m_strName);
m_ctlAPI.AddString("WmiSetAndCommitObject");
m_ctlAPI.AddString("WmiCommitObject");
m_ctlAPI.AddString("WmiSetObjectProp*n + WmiCommitObject");
m_ctlAPI.AddString("WmiSetObjectProps + WmiCommitObject");
m_ctlAPI.AddString("WmiReportEvent");
m_ctlAPI.AddString("WmiReportEventBlob");
int iTemp;
iTemp =
theApp.GetProfileInt("Settings", "API", API_WmiCommitObject);
m_ctlAPI.SetCurSel(iTemp);
iTemp =
theApp.GetProfileInt("Settings", "Type", EVENT_DWORD);
m_ctlEventTypes.SetCurSel(iTemp);
OnSelchangeEventTypes();
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CTestDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CTestDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CTestDlg::OnConnect()
{
FreeHandles();
Connect();
}
void CTestDlg::OnSelchangeEventTypes()
{
EVENT_TYPE type = (EVENT_TYPE) m_ctlEventTypes.GetCurSel();
SetDlgItemText(IDC_QUERY, m_pEvents[type]->m_strQuery);
// This should only be enabled if we're not using a blob
// or generic
if (type == EVENT_Blob)
{
m_ctlAPI.SetCurSel(API_WmiReportEventBlob);
m_ctlAPI.EnableWindow(FALSE);
GetDlgItem(IDC_EVENT_SD)->EnableWindow(FALSE);
}
else if (type == EVENT_Generic)
{
m_ctlAPI.SetCurSel(API_WmiReportEvent);
m_ctlAPI.EnableWindow(FALSE);
GetDlgItem(IDC_EVENT_SD)->EnableWindow(FALSE);
}
else
{
m_ctlAPI.EnableWindow(TRUE);
GetDlgItem(IDC_EVENT_SD)->EnableWindow(TRUE);
}
}
void CTestDlg::OnSend()
{
CWaitCursor wait;
int nEvents = GetDlgItemInt(IDC_COUNT);
EVENT_TYPE type = (EVENT_TYPE) m_ctlEventTypes.GetCurSel();
API_TYPE api = (API_TYPE) m_ctlAPI.GetCurSel();
if (type != EVENT_Blob && api == API_WmiReportEventBlob)
{
AfxMessageBox(
"The selected event type can't be fired using ReportEventBlob.");
return;
}
DWORD dwBegin;
// I'm going to repeat the for/loop for every API so I don't have to have
// a switch statement inside the loop (which would degrade throughput
// speeds).
if (api == API_WmiReportEvent || api == API_WmiReportEventBlob)
{
CNCEvent *pEvent = m_pEvents[type];
dwBegin = GetTickCount();
for (int i = 0; i < nEvents; i++)
pEvent->ReportEvent();
}
else
{
CPropEvent *pEvent = (CPropEvent*) m_pEvents[type];
if (api == API_WmiSetAndCommitObject)
{
dwBegin = GetTickCount();
for (int i = 0; i < nEvents; i++)
pEvent->SetAndFire(WMI_SENDCOMMIT_SET_NOT_REQUIRED);
}
else if (api == API_WmiCommitObject)
{
dwBegin = GetTickCount();
for (int i = 0; i < nEvents; i++)
pEvent->Commit();
}
else if (api == API_WmiSetObjectPropsWmiCommitObject)
{
dwBegin = GetTickCount();
for (int i = 0; i < nEvents; i++)
{
pEvent->SetPropsWithOneCall();
pEvent->Commit();
}
}
else if (api == API_WmiSetObjectPropWmiCommitObject)
{
dwBegin = GetTickCount();
for (int i = 0; i < nEvents; i++)
{
pEvent->SetPropsWithManyCalls();
pEvent->Commit();
}
}
}
// Now figure out the stats.
DWORD dwEnd = GetTickCount();
CString strTemp;
// Make sure the difference isn't 0.
if (dwEnd == dwBegin)
dwEnd++;
// Seconds elapsed
strTemp.Format(_T("%.2f"), (double) (dwEnd - dwBegin) / 1000.0);
SetDlgItemText(IDS_TIME, strTemp);
// Events per second
strTemp.Format(_T("%.2f"),
(double) nEvents / ((double) (dwEnd - dwBegin) / 1000.0));
SetDlgItemText(IDS_PER_SECOND, strTemp);
}
void CTestDlg::AddStatus(LPCTSTR szMsg)
{
::SendMessage(m_hwndStatus, EM_SETSEL, -1, -1);
::SendMessage(m_hwndStatus, EM_REPLACESEL, FALSE, (LPARAM) szMsg);
}
HRESULT WINAPI CTestDlg::EventSourceCallback(
HANDLE hSource,
EVENT_SOURCE_MSG msg,
LPVOID pUser,
LPVOID pData)
{
CTestDlg *pThis = (CTestDlg*) pUser;
switch(msg)
{
case ESM_START_SENDING_EVENTS:
pThis->AddStatus("ESM_START_SENDING_EVENTS\r\n\r\n");
break;
case ESM_STOP_SENDING_EVENTS:
pThis->AddStatus("ESM_STOP_SENDING_EVENTS\r\n\r\n");
break;
case ESM_NEW_QUERY:
{
ES_NEW_QUERY *pQuery = (ES_NEW_QUERY*) pData;
CString strMsg;
strMsg.Format(
"ESM_NEW_QUERY: ID %d, %S:%S\r\n\r\n",
pQuery->dwID,
pQuery->szQueryLanguage,
pQuery->szQuery);
pThis->AddStatus(strMsg);
break;
}
case ESM_CANCEL_QUERY:
{
ES_CANCEL_QUERY *pQuery = (ES_CANCEL_QUERY*) pData;
CString strMsg;
strMsg.Format(
"ESM_CANCEL_QUERY: ID %d\r\n\r\n",
pQuery->dwID);
pThis->AddStatus(strMsg);
break;
}
case ESM_ACCESS_CHECK:
{
ES_ACCESS_CHECK *pCheck = (ES_ACCESS_CHECK*) pData;
CString strMsg;
strMsg.Format(
"ESM_ACCESS_CHECK: %S:%S, pSID = 0x%X\r\n\r\n",
pCheck->szQueryLanguage,
pCheck->szQuery,
pCheck->pSid);
pThis->AddStatus(strMsg);
break;
}
default:
break;
}
return S_OK;
}
void CTestDlg::OnDestroy()
{
CDialog::OnDestroy();
UpdateData(TRUE);
}
void CTestDlg::OnCopy()
{
// Set the ANSI text data.
CString strQuery;
GetDlgItemText(IDC_QUERY, strQuery);
DWORD dwSize = strQuery.GetLength() + 1;
HGLOBAL hglob = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, dwSize);
memcpy(GlobalLock(hglob), (LPCTSTR) strQuery, dwSize);
GlobalUnlock(hglob);
::OpenClipboard(NULL);
SetClipboardData(CF_TEXT, hglob);
CloseClipboard();
}
void CTestDlg::OnClear()
{
SetDlgItemText(IDC_CALLBACK, "");
}
void CTestDlg::OnConnectionSd()
{
/*
CSecDlg dlg;
if (dlg.DoModal() == IDOK)
WmiSetConnectionSecurity(g_hConnection, dlg.m_pSD);
*/
}
void CTestDlg::OnEventSd()
{
/*
CSecDlg dlg;
if (dlg.DoModal() == IDOK)
{
EVENT_TYPE type = (EVENT_TYPE) m_ctlEventTypes.GetCurSel();
CPropEvent *pEvent = (CPropEvent*) m_pEvents[type];
WmiSetObjectSecurity(pEvent->m_hEvent, dlg.m_pSD);
}
*/
}