|
|
// ShowPerfLibDlg.cpp : implementation file
//
#include "stdafx.h"
#include "ShowPerfLib.h"
#include "ShowPerfLibDlg.h"
#include "PerfSelection.h"
#include "ntreg.h"
#include "listperf.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
/////////////////////////////////////////////////////////////////////////////
// CShowPerfLibDlg dialog
CShowPerfLibDlg::CShowPerfLibDlg(CWnd* pParent /*=NULL*/) : CDialog(CShowPerfLibDlg::IDD, pParent) { //{{AFX_DATA_INIT(CShowPerfLibDlg)
m_strRequest = _T(""); //}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_strService = _T(""); }
CShowPerfLibDlg::CShowPerfLibDlg(CString strService, BOOL bRefCheck, CWnd* pParent /*=NULL*/) : m_strService( strService ), m_bRefCheck(bRefCheck), CDialog(CShowPerfLibDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); }
CShowPerfLibDlg::~CShowPerfLibDlg() { CloseLibrary(); FreeLibrary( m_hLib ); }
void CShowPerfLibDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CShowPerfLibDlg)
DDX_Control(pDX, IDC_GET_COUNTER, m_wndGetCounter); DDX_Control(pDX, IDC_ERRORS, m_wndErrorLog); DDX_Control(pDX, IDC_PERFTREE, m_wndPerfTree); DDX_Text(pDX, IDC_REQUEST, m_strRequest); //}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CShowPerfLibDlg, CDialog) //{{AFX_MSG_MAP(CShowPerfLibDlg)
ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_EN_CHANGE(IDC_REQUEST, OnChangeRequest) ON_BN_CLICKED(IDC_GET_COUNTER, OnGetCounter) //}}AFX_MSG_MAP
END_MESSAGE_MAP()
///////////// ////////////////////////////////////////////////////////////////
// CShowPerfLibDlg message handlers
BOOL CShowPerfLibDlg::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
SetWindowText( m_strService );
int nCol; nCol = m_wndErrorLog.InsertColumn(0, "Type", LVCFMT_LEFT, 75 ); nCol = m_wndErrorLog.InsertColumn(1, "Description", LVCFMT_LEFT, 500 );
InitPerfLibTree();
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 CShowPerfLibDlg::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 CShowPerfLibDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; }
/////////////////////////////////////////////////////////////////////////////
//
// Perf Lib methods
//
/////////////////////////////////////////////////////////////////////////////
BOOL CShowPerfLibDlg::InitPerfLibTree() { BOOL bRet = TRUE;
CWaitCursor wc;
if (InitService()) { if ( OpenLibrary() ) { bRet = GetData(); } }
return bRet; }
BOOL CShowPerfLibDlg::InitService() { BOOL bRet = TRUE;
CNTRegistry Reg; WCHAR wszKey[128];
char szLog[256];
swprintf(wszKey, L"SYSTEM\\CurrentControlSet\\Services\\%S\\Performance", m_strService);
if ( CNTRegistry::no_error == Reg.Open( HKEY_LOCAL_MACHINE, wszKey ) ) { WCHAR* wszTemp; Reg.GetStr(L"Library", &wszTemp); m_strPerfLib = wszTemp; delete [] wszTemp; sprintf(szLog, "Library Name: %s", m_strPerfLib); Log( PERF_INFO, szLog );
Reg.GetStr(L"Open", &wszTemp); m_strOpen = wszTemp; delete [] wszTemp; sprintf(szLog, "Open Function Name: %s", m_strOpen); Log( PERF_INFO, szLog );
Reg.GetStr(L"Collect", &wszTemp); m_strCollect = wszTemp; delete [] wszTemp; sprintf(szLog, "Collect Function Name: %s", m_strCollect); Log( PERF_INFO, szLog );
Reg.GetStr(L"Close", &wszTemp); m_strClose = wszTemp; delete [] wszTemp; sprintf(szLog, "Close Function Name: %s", m_strClose); Log( PERF_INFO, szLog ); } else { sprintf(szLog, "Counld not open the %S registry key", wszKey); Log( PERF_FAILURE, szLog );
bRet = FALSE; }
return bRet; }
BOOL CShowPerfLibDlg::OpenLibrary() { BOOL bRet = TRUE;
char szLog[256];
m_hLib = LoadLibrary( (LPCSTR)m_strPerfLib );
if ( NULL != m_hLib ) { sprintf(szLog, "Loaded the %s Performance Library", m_strPerfLib); Log( PERF_SUCCESS, szLog );
m_pfnOpenProc = (PM_OPEN_PROC*) GetProcAddress( m_hLib, m_strOpen ); m_pfnCollectProc = (PM_COLLECT_PROC*) GetProcAddress( m_hLib, m_strCollect ); m_pfnCloseProc = (PM_CLOSE_PROC*) GetProcAddress( m_hLib, m_strClose );
bRet = ( ( NULL != m_pfnOpenProc ) && ( NULL != m_pfnCollectProc ) && ( NULL != m_pfnCloseProc ) );
Log (( NULL != m_pfnOpenProc )?PERF_SUCCESS:PERF_FAILURE, "Get Open Procedure Address"); Log (( NULL != m_pfnCollectProc )?PERF_SUCCESS:PERF_FAILURE, "Get Collect Procedure Address"); Log (( NULL != m_pfnCloseProc )?PERF_SUCCESS:PERF_FAILURE, "Get Close Procedure Address"); } else { sprintf(szLog, "Could not load the %s Performance Library", m_strPerfLib); Log( PERF_FAILURE, szLog );
bRet = FALSE; }
if ( bRet ) { bRet = ( m_pfnOpenProc( NULL ) == ERROR_SUCCESS ); Log( bRet?PERF_SUCCESS:PERF_FAILURE, "Opening Performance Library" );
if ( bRet && m_bRefCheck ) { bRet = ( m_pfnOpenProc( NULL ) == ERROR_SUCCESS ); Log( bRet?PERF_SUCCESS:PERF_FAILURE, "Opening Performance Library" );
if ( bRet ) { bRet = ( m_pfnCloseProc() == ERROR_SUCCESS ); Log( bRet?PERF_SUCCESS:PERF_FAILURE, "Closing Performance Library" ); } } }
return bRet; }
BOOL CShowPerfLibDlg::Collect( CString strSpace ) { BOOL bRet = TRUE;
int nRet = ERROR_MORE_DATA; char szLog[256];
DWORD dwGuardSize = 1024; DWORD dwSize = 64000;
BOOL bValid = HeapValidate( GetProcessHeap(), NULL, NULL );
BYTE* pSafeBuffer = new BYTE[dwSize + ( 2 * dwGuardSize )];
memset( pSafeBuffer, 0xFFFFFFFF, dwSize + ( 2 * dwGuardSize ) ); BYTE* pBuffer = pSafeBuffer + dwGuardSize; BYTE* pBufferPtr = NULL;
DWORD dwNumClasses = 0; DWORD dwBufferSize = 0;
WCHAR wszSpace[256];
mbstowcs( wszSpace, (LPCSTR)strSpace, 256 );
while (ERROR_MORE_DATA == nRet) { pBufferPtr = pBuffer; dwBufferSize = dwSize;
nRet = m_pfnCollectProc( wszSpace, (LPVOID*)(&pBufferPtr), &dwBufferSize, &dwNumClasses ); sprintf(szLog, "Collect function called using %S counters", wszSpace); Log((nRet==ERROR_SUCCESS)?PERF_SUCCESS:((nRet==ERROR_MORE_DATA)?PERF_MORE_DATA:PERF_FAILURE), szLog );
if (ERROR_SUCCESS == nRet) { sprintf(szLog, "Required buffer size: %d bytes", dwBufferSize); Log( PERF_INFO, szLog ); sprintf(szLog, "Number of objects returned: %d", dwNumClasses); Log( PERF_INFO, szLog );
try { BuildSubTree( strSpace, pBuffer, dwNumClasses ); } catch(...) { AfxMessageBox("Exception thrown while processing blob"); } } else if ( ERROR_MORE_DATA == nRet ) { dwSize += 8000;
if ( NULL != pSafeBuffer ) { delete [] pSafeBuffer; }
pSafeBuffer = new BYTE[dwSize + ( 2 * dwGuardSize )]; memset( pSafeBuffer, 0xFFFFFFFF, dwSize + ( 2 * dwGuardSize ) ); } else { bRet = FALSE; } }
if ( NULL != pBuffer ) { delete [] pSafeBuffer; }
return bRet; }
BOOL CShowPerfLibDlg::GetData() { BOOL bRet = TRUE; char szSpace[16];
for ( int i = 0; (i < 2) && bRet; i++ ) { if ( 0 == i ) { strcpy (szSpace, "Global"); } else { strcpy (szSpace, "Costly"); }
bRet = Collect( szSpace ); }
return bRet; }
BOOL CShowPerfLibDlg::BuildSubTree( CString strSpace, BYTE* pBlob, DWORD dwNumObjects) { BOOL bRet = TRUE;
HTREEITEM hSpace = m_wndPerfTree.InsertItem( strSpace );
// Object
PERF_OBJECT_TYPE* pObj = (PERF_OBJECT_TYPE*)pBlob;
for ( DWORD dwObj = 0; dwObj < dwNumObjects; dwObj++ ) { CString str;
char* szName; m_TitleLibrary.GetName(pObj->ObjectNameTitleIndex, &szName);
char szClassName[256]; sprintf(szClassName, "%s Class", szName ); HTREEITEM hClass = m_wndPerfTree.InsertItem( szClassName, hSpace );
str.Format("TotalByteLength: %d", pObj->TotalByteLength); m_wndPerfTree.InsertItem( str, hClass ); str.Format("DefinitionLength: %d", pObj->DefinitionLength); m_wndPerfTree.InsertItem( str, hClass ); str.Format("HeaderLength: %d", pObj->HeaderLength); m_wndPerfTree.InsertItem( str, hClass ); str.Format("ObjectNameTitleIndex: %d", pObj->ObjectNameTitleIndex); m_wndPerfTree.InsertItem( str, hClass ); str.Format("ObjectHelpTitleIndex: %d", pObj->ObjectHelpTitleIndex); m_wndPerfTree.InsertItem( str, hClass ); str.Format("DetailLevel: %d", pObj->DetailLevel); m_wndPerfTree.InsertItem( str, hClass ); str.Format("NumCounters: %d", pObj->NumCounters); m_wndPerfTree.InsertItem( str, hClass ); str.Format("DefaultCounter: %d", pObj->DefaultCounter); m_wndPerfTree.InsertItem( str, hClass ); str.Format("NumInstances: %d", pObj->NumInstances); m_wndPerfTree.InsertItem( str, hClass ); str.Format("CodePage: %d", pObj->CodePage); m_wndPerfTree.InsertItem( str, hClass ); str.Format("PerfTime: %d", pObj->PerfTime); m_wndPerfTree.InsertItem( str, hClass ); str.Format("PerfFreq: %d", pObj->PerfFreq); m_wndPerfTree.InsertItem( str, hClass );
// Counters
PERF_COUNTER_DEFINITION* pCtrDef = (PERF_COUNTER_DEFINITION*)((DWORD)pObj + pObj->HeaderLength);
for ( DWORD dwCtr = 0; dwCtr < pObj->NumCounters; dwCtr++ ) { char szCounterName[256];
m_TitleLibrary.GetName( pCtrDef->CounterNameTitleIndex, &szName ); sprintf(szCounterName, "%s Counter", szName);
HTREEITEM hCtr = m_wndPerfTree.InsertItem( szCounterName, hClass );
str.Format("ByteLength: %d", pCtrDef->ByteLength); m_wndPerfTree.InsertItem( str, hCtr ); str.Format("CounterNameTitleIndex: %d", pCtrDef->CounterNameTitleIndex); m_wndPerfTree.InsertItem( str, hCtr ); str.Format("CounterHelpTitleIndex: %d", pCtrDef->CounterHelpTitleIndex); m_wndPerfTree.InsertItem( str, hCtr ); str.Format("DefaultScale: %d", pCtrDef->DefaultScale); m_wndPerfTree.InsertItem( str, hCtr ); str.Format("DetailLevel: %d", pCtrDef->DetailLevel); m_wndPerfTree.InsertItem( str, hCtr ); str.Format("CounterType: 0x%X (%s Base)", pCtrDef->CounterType, ( PERF_COUNTER_BASE == (pCtrDef->CounterType & 0x00070000))?"Is a ":"Is not a "); m_wndPerfTree.InsertItem( str, hCtr ); str.Format("CounterSize: %d", pCtrDef->CounterSize); m_wndPerfTree.InsertItem( str, hCtr ); str.Format("CounterOffset: %d", pCtrDef->CounterOffset); m_wndPerfTree.InsertItem( str, hCtr );
pCtrDef = (PERF_COUNTER_DEFINITION*)((DWORD)pCtrDef + pCtrDef->ByteLength); }
// Instances
PERF_INSTANCE_DEFINITION* pInstDef = (PERF_INSTANCE_DEFINITION*)((DWORD)pObj + pObj->DefinitionLength);
for ( LONG lInstance = 0; lInstance < pObj->NumInstances; lInstance++ ) { char szInstanceName[256]; sprintf(szInstanceName, "%S Instance", (WCHAR*)((DWORD)pInstDef + pInstDef->NameOffset)); HTREEITEM hInst = m_wndPerfTree.InsertItem( szInstanceName, hClass );
str.Format("ByteLength: %d", pInstDef->ByteLength); m_wndPerfTree.InsertItem( str, hInst ); str.Format("ParentObjectTitleIndex: %d", pInstDef->ParentObjectTitleIndex); m_wndPerfTree.InsertItem( str, hInst ); str.Format("ParentObjectInstance: %d", pInstDef->ParentObjectInstance); m_wndPerfTree.InsertItem( str, hInst ); str.Format("UniqueID: %d", pInstDef->UniqueID); m_wndPerfTree.InsertItem( str, hInst ); str.Format("NameOffset: %d", pInstDef->NameOffset); m_wndPerfTree.InsertItem( str, hInst ); str.Format("NameLength: %d", pInstDef->NameLength); m_wndPerfTree.InsertItem( str, hInst );
// Instance Counter Data
PERF_COUNTER_BLOCK* pCtrBlock = (PERF_COUNTER_BLOCK*)((DWORD)pInstDef + pInstDef->ByteLength); BYTE* pCurrCtr = (BYTE*)pCtrBlock;
PERF_COUNTER_DEFINITION* pCtrDef = (PERF_COUNTER_DEFINITION*)((DWORD)pObj + pObj->HeaderLength);
for ( DWORD dwCtr = 0; dwCtr < pObj->NumCounters; dwCtr++ ) { char* szName; m_TitleLibrary.GetName( pCtrDef->CounterNameTitleIndex, &szName );
switch (pCtrDef->CounterSize) { case 0: { str.Format("%s data: <zero length>", szName ); m_wndPerfTree.InsertItem( str, hInst ); }break; case 4: { str.Format("%s data: %d", szName, (DWORD)(*(pCurrCtr + pCtrDef->CounterOffset))); m_wndPerfTree.InsertItem( str, hInst ); }break; case 8: { str.Format("%s data: %I64d", szName, (__int64)(*(pCurrCtr + pCtrDef->CounterOffset))); m_wndPerfTree.InsertItem( str, hInst ); }break;
default: { str.Format("%s data: <unhandled>", szName ); m_wndPerfTree.InsertItem( str, hInst ); }break; }
pCtrDef = (PERF_COUNTER_DEFINITION*)((DWORD)pCtrDef + pCtrDef->ByteLength); }
pInstDef = (PERF_INSTANCE_DEFINITION*)((DWORD)pCtrBlock + pCtrBlock->ByteLength); }
pObj = (PERF_OBJECT_TYPE*)((DWORD)pObj + pObj->TotalByteLength); }
return bRet; }
BOOL CShowPerfLibDlg::CloseLibrary() { BOOL bRet = TRUE;
DWORD dwRet = m_pfnCloseProc();
/* if ( ERROR_SUCCESS != dwRet )
bRet = FALSE;
Log( bRet?PERF_SUCCESS:PERF_FAILURE, "Closing Performance Library" ); */ return bRet; }
void CShowPerfLibDlg::Log( DWORD dwState, CString strDesc ) { CString strState; int nIndex = -1; BOOL bErr;
switch( dwState ) { case PERF_SUCCESS: { strState = "Success"; }break; case PERF_INFO: { strState = "Information"; }break; case PERF_MORE_DATA: { strState = "More Data"; }break; case PERF_WARNING: { strState = "Warning"; }break; case PERF_FAILURE: { strState = "Failure"; }break; default: { strState = "Unknown"; }break; };
nIndex = m_wndErrorLog.InsertItem( m_wndErrorLog.GetItemCount() , strState ); bErr = m_wndErrorLog.SetItemText( nIndex, 1, strDesc );
}
void CShowPerfLibDlg::OnChangeRequest() {
}
void CShowPerfLibDlg::OnGetCounter() { UpdateData();
Collect( m_strRequest );
m_strRequest.Empty(); UpdateData( FALSE ); }
|