548 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			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);
 | |
|     }
 | |
| */
 | |
| }
 |