// // Driver Verifier UI // Copyright (c) Microsoft Corporation, 1999 // // // // module: DCntPage.cpp // author: DMihai // created: 11/1/00 // // Description: // #include "stdafx.h" #include "verifier.h" #include "DCntPage.h" #include "VrfUtil.h" #include "VGlobal.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // // Timer ID // #define REFRESH_TIMER_ID 0x1234 // // Help IDs // static DWORD MyHelpIds[] = { IDC_PERDRVC_DRIVER_COMBO, IDH_DV_Counters_DriverList, IDC_PERDRVC_LIST, IDH_DV_DriverCounters, 0, 0 }; ///////////////////////////////////////////////////////////////////////////// // CDriverCountersPage property page IMPLEMENT_DYNCREATE(CDriverCountersPage, CVerifierPropertyPage) CDriverCountersPage::CDriverCountersPage() : CVerifierPropertyPage(CDriverCountersPage::IDD) { //{{AFX_DATA_INIT(CDriverCountersPage) //}}AFX_DATA_INIT m_nSortColumnIndex = 0; m_bAscendSortName = FALSE; m_bAscendSortValue = FALSE; m_uTimerHandler = 0; m_pParentSheet = NULL; } CDriverCountersPage::~CDriverCountersPage() { } void CDriverCountersPage::DoDataExchange(CDataExchange* pDX) { if( ! pDX->m_bSaveAndValidate ) { // // Query the kernel // VrfGetRuntimeVerifierData( &m_RuntimeVerifierData ); } CVerifierPropertyPage::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDriverCountersPage) DDX_Control(pDX, IDC_PERDRVC_DRIVER_COMBO, m_DriversCombo); DDX_Control(pDX, IDC_PERDRVC_NEXT_DESCR_STATIC, m_NextDescription); DDX_Control(pDX, IDC_PERDRVC_LIST, m_CountersList); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDriverCountersPage, CVerifierPropertyPage) //{{AFX_MSG_MAP(CDriverCountersPage) ON_WM_TIMER() ON_CBN_SELENDOK(IDC_PERDRVC_DRIVER_COMBO, OnSelendokDriverCombo) ON_NOTIFY(LVN_COLUMNCLICK, IDC_PERDRVC_LIST, OnColumnclickPerdrvcList) ON_WM_CONTEXTMENU() ON_MESSAGE( WM_HELP, OnHelp ) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////// VOID CDriverCountersPage::SetupListHeader() { LVCOLUMN lvColumn; CRect rectWnd; CString strCounter, strValue; VERIFY( strCounter.LoadString( IDS_COUNTER ) ); VERIFY( strValue.LoadString( IDS_VALUE ) ); // // List's regtangle // m_CountersList.GetClientRect( &rectWnd ); // // Column 0 - counter // ZeroMemory( &lvColumn, sizeof( lvColumn ) ); lvColumn.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH; lvColumn.fmt = LVCFMT_LEFT; lvColumn.iSubItem = 0; lvColumn.pszText = strCounter.GetBuffer( strCounter.GetLength() + 1 ); lvColumn.cx = (int)( rectWnd.Width() * 0.50 ); VERIFY( m_CountersList.InsertColumn( 0, &lvColumn ) != -1 ); strCounter.ReleaseBuffer(); // // Column 1 // lvColumn.iSubItem = 1; lvColumn.pszText = strValue.GetBuffer( strValue.GetLength() + 1 ); lvColumn.cx = (int)( rectWnd.Width() * 0.47 ); VERIFY( m_CountersList.InsertColumn( 1, &lvColumn ) != -1 ); strValue.ReleaseBuffer(); } ///////////////////////////////////////////////////////////// VOID CDriverCountersPage::FillTheList() { CRuntimeDriverData *pRuntimeDriverData; pRuntimeDriverData = GetCurrentDrvRuntimeData(); AddAllListItems( pRuntimeDriverData ); } ///////////////////////////////////////////////////////////// VOID CDriverCountersPage::AddAllListItems( CRuntimeDriverData *pRuntimeDriverData ) { if( NULL != pRuntimeDriverData ) { ASSERT_VALID( pRuntimeDriverData ); // // N.B. // // If you change this order then you need to change GetCounterValue as well // AddCounterInList( 0, IDS_CURRENTPAGEDPOOLALLOCATIONS_LIST, pRuntimeDriverData->CurrentPagedPoolAllocations ); AddCounterInList( 1, IDS_PEAKPAGEDPOOLALLOCATIONS_LIST, pRuntimeDriverData->PeakPagedPoolAllocations ); AddCounterInList( 2, IDS_PAGEDPOOLUSAGEINBYTES_LIST, pRuntimeDriverData->PagedPoolUsageInBytes ); AddCounterInList( 3, IDS_PEAKPAGEDPOOLUSAGEINBYTES_LIST, pRuntimeDriverData->PeakPagedPoolUsageInBytes ); AddCounterInList( 4, IDS_CURRENTNONPAGEDPOOLALLOCATIONS_LIST, pRuntimeDriverData->CurrentNonPagedPoolAllocations ); AddCounterInList( 5, IDS_PEAKNONPAGEDPOOLALLOCATIONS_LIST, pRuntimeDriverData->PeakNonPagedPoolAllocations ); AddCounterInList( 6, IDS_NONPAGEDPOOLUSAGEINBYTES_LIST, pRuntimeDriverData->NonPagedPoolUsageInBytes ); AddCounterInList( 7, IDS_PEAKNONPAGEDPOOLUSAGEINBYTES_LIST, pRuntimeDriverData->PeakNonPagedPoolUsageInBytes ); } else { // // N.B. // // If you change this order then you need to change GetCounterValue as well // AddCounterInList( 0, IDS_CURRENTPAGEDPOOLALLOCATIONS_LIST ); AddCounterInList( 1, IDS_PEAKPAGEDPOOLALLOCATIONS_LIST ); AddCounterInList( 2, IDS_PAGEDPOOLUSAGEINBYTES_LIST ); AddCounterInList( 3, IDS_PEAKPAGEDPOOLUSAGEINBYTES_LIST ); AddCounterInList( 4, IDS_CURRENTNONPAGEDPOOLALLOCATIONS_LIST ); AddCounterInList( 5, IDS_PEAKNONPAGEDPOOLALLOCATIONS_LIST ); AddCounterInList( 6, IDS_NONPAGEDPOOLUSAGEINBYTES_LIST ); AddCounterInList( 7, IDS_PEAKNONPAGEDPOOLUSAGEINBYTES_LIST ); } } ///////////////////////////////////////////////////////////// VOID CDriverCountersPage::RefreshTheList() { INT nListItems; INT nCrtListItem; INT_PTR nCrtCounterIndex; SIZE_T sizeValue; CRuntimeDriverData *pRuntimeDriverData; pRuntimeDriverData = GetCurrentDrvRuntimeData(); nListItems = m_CountersList.GetItemCount(); if( NULL != pRuntimeDriverData ) { for( nCrtListItem = 0; nCrtListItem < nListItems; nCrtListItem += 1 ) { nCrtCounterIndex = m_CountersList.GetItemData( nCrtListItem ); sizeValue = GetCounterValue( nCrtCounterIndex, pRuntimeDriverData ); UpdateCounterValueInList( nCrtListItem, sizeValue ); } } else { // // N.B. // // If you change this order then you need to // change AddAllListItems as well // for( nCrtListItem = 0; nCrtListItem < nListItems; nCrtListItem += 1 ) { UpdateCounterValueInList( nCrtListItem, g_szVoidText ); } } SortTheList(); } ///////////////////////////////////////////////////////////// INT CDriverCountersPage::AddCounterInList( INT nItemData, ULONG uIdResourceString ) { INT nActualIndex; LVITEM lvItem; CString strName; nActualIndex = -1; VERIFY( strName.LoadString( uIdResourceString ) ); ZeroMemory( &lvItem, sizeof( lvItem ) ); // // LVITEM's member pszText is not a const pointer // so we need to GetBuffer here :-( // // // Sub-item 0 - counter's name // lvItem.pszText = strName.GetBuffer( strName.GetLength() + 1 ); if( NULL == lvItem.pszText ) { goto Done; } lvItem.mask = LVIF_TEXT | LVIF_PARAM; lvItem.lParam = nItemData; lvItem.iItem = m_CountersList.GetItemCount(); nActualIndex = m_CountersList.InsertItem( &lvItem ); if( nActualIndex < 0 ) { // // Could not add an item in the list - give up // goto Done; } Done: // // All done // return nActualIndex; } ///////////////////////////////////////////////////////////// VOID CDriverCountersPage::AddCounterInList( INT nItemData, ULONG uIdResourceString, SIZE_T sizeValue ) { INT nActualIndex; nActualIndex = AddCounterInList( nItemData, uIdResourceString ); if( nActualIndex < 0 ) { // // Could not add an item in the list - give up // goto Done; } // // Sub-item 1 - counter's value // UpdateCounterValueInList( nActualIndex, sizeValue ); Done: // // All done // NOTHING; } ///////////////////////////////////////////////////////////// SIZE_T CDriverCountersPage::GetCounterValue( INT_PTR nCounterIndex, CRuntimeDriverData *pRuntimeDriverData /*= NULL*/ ) { SIZE_T sizeValue; if( NULL == pRuntimeDriverData ) { pRuntimeDriverData = GetCurrentDrvRuntimeData(); } if( NULL == pRuntimeDriverData ) { // // No driver is curently selected in the combo // return 0; } // // N.B. // // If you change this switch statement you need to change AddAllListItems as well // switch( nCounterIndex ) { case 0: sizeValue = pRuntimeDriverData->CurrentPagedPoolAllocations; break; case 1: sizeValue = pRuntimeDriverData->PeakPagedPoolAllocations; break; case 2: sizeValue = pRuntimeDriverData->PagedPoolUsageInBytes; break; case 3: sizeValue = pRuntimeDriverData->PeakPagedPoolUsageInBytes; break; case 4: sizeValue = pRuntimeDriverData->CurrentNonPagedPoolAllocations; break; case 5: sizeValue = pRuntimeDriverData->PeakNonPagedPoolAllocations; break; case 6: sizeValue = pRuntimeDriverData->NonPagedPoolUsageInBytes; break; case 7: sizeValue = pRuntimeDriverData->PeakNonPagedPoolUsageInBytes; break; default: // // Oops, how did we get here ?!? // ASSERT( FALSE ); sizeValue = 0; break; } return sizeValue; } ///////////////////////////////////////////////////////////// BOOL CDriverCountersPage::GetCounterName( LPARAM lItemData, TCHAR *szCounterName, ULONG uCounterNameBufferLen ) { INT nItemIndex; BOOL bResult; LVFINDINFO FindInfo; LVITEM lvItem; bResult = FALSE; ZeroMemory( &FindInfo, sizeof( FindInfo ) ); FindInfo.flags = LVFI_PARAM; FindInfo.lParam = lItemData; nItemIndex = m_CountersList.FindItem( &FindInfo ); if( nItemIndex < 0 || nItemIndex > 7 ) { ASSERT( FALSE ); } else { // // Found our item - get the name // ZeroMemory( &lvItem, sizeof( lvItem ) ); lvItem.mask = LVIF_TEXT; lvItem.iItem = nItemIndex; lvItem.iSubItem = 0; lvItem.pszText = szCounterName; lvItem.cchTextMax = uCounterNameBufferLen; bResult = m_CountersList.GetItem( &lvItem ); if( bResult == FALSE ) { // // Could not get the current item's attributes?!? // ASSERT( FALSE ); } } return bResult; } ///////////////////////////////////////////////////////////// VOID CDriverCountersPage::UpdateCounterValueInList( INT nItemIndex, LPTSTR szValue ) { LVITEM lvItem; // // Update the list item // ZeroMemory( &lvItem, sizeof( lvItem ) ); lvItem.mask = LVIF_TEXT; lvItem.iItem = nItemIndex; lvItem.iSubItem = 1; lvItem.pszText = szValue; VERIFY( m_CountersList.SetItem( &lvItem ) ); } ///////////////////////////////////////////////////////////// VOID CDriverCountersPage::UpdateCounterValueInList( INT nItemIndex, SIZE_T sizeValue ) { TCHAR szValue[ 32 ]; #ifndef _WIN64 // // 32 bit SIZE_T // _sntprintf( szValue, ARRAY_LENGTH( szValue ), _T( "%u" ), sizeValue ); #else // // 64 bit SIZE_T // _sntprintf( szValue, ARRAY_LENGTH( szValue ), _T( "%I64u" ), sizeValue ); #endif szValue[ ARRAY_LENGTH( szValue ) - 1 ] = 0; UpdateCounterValueInList( nItemIndex, szValue ); } ///////////////////////////////////////////////////////////// VOID CDriverCountersPage::RefreshCombo() { BOOL *pbAlreadyInCombo; CRuntimeDriverData *pRuntimeDriverData; INT_PTR nDrivers; INT_PTR nCrtDriver; INT nCrtSelectedItem; INT nCrtItemIndex; INT nComboItemCount; INT nActualIndex; CString strCurrentDriverName; CString strDriverName; nDrivers = m_RuntimeVerifierData.m_RuntimeDriverDataArray.GetSize(); if( 0 >= nDrivers ) { // // No drivers are currently verified - delete the combo-box content // m_DriversCombo.ResetContent(); m_DriversCombo.SetCurSel( CB_ERR ); m_DriversCombo.EnableWindow( FALSE ); OnSelendokDriverCombo(); } else { nCrtSelectedItem = 0; nComboItemCount = m_DriversCombo.GetCount(); // // Note the currently selected driver name // GetCurrentSelDriverName( strCurrentDriverName ); // // Allocate an array of BOOL values, one for each driver in // our runtime data array // pbAlreadyInCombo = new BOOL[ nDrivers ]; if( NULL == pbAlreadyInCombo ) { goto Done; } for( nCrtDriver = 0; nCrtDriver < nDrivers; nCrtDriver++ ) { pbAlreadyInCombo[ nCrtDriver ] = FALSE; } // // Parse all the items currently in the combo-box // for( nCrtItemIndex = 0; nCrtItemIndex < nComboItemCount; nCrtItemIndex++ ) { m_DriversCombo.GetLBText( nCrtItemIndex, strDriverName ); // // Parse all the currently verified drivers // for( nCrtDriver = 0; nCrtDriver < nDrivers; nCrtDriver++ ) { pRuntimeDriverData = m_RuntimeVerifierData.m_RuntimeDriverDataArray.GetAt( nCrtDriver ); ASSERT_VALID( pRuntimeDriverData ); if( strDriverName.CompareNoCase( pRuntimeDriverData->m_strName ) == 0 ) { pbAlreadyInCombo[ nCrtDriver ] = TRUE; break; } } if( nCrtDriver >= nDrivers ) { // // We need to delete the current combo item because // the corresponfing driver is no longer verified // m_DriversCombo.DeleteString( nCrtItemIndex ); nCrtItemIndex--; nComboItemCount--; } } // // Add the new items in the combo // for( nCrtDriver = 0; nCrtDriver < nDrivers; nCrtDriver++ ) { if( FALSE == pbAlreadyInCombo[ nCrtDriver ] ) { pRuntimeDriverData = m_RuntimeVerifierData.m_RuntimeDriverDataArray.GetAt( nCrtDriver ); ASSERT_VALID( pRuntimeDriverData ); nActualIndex = m_DriversCombo.AddString( pRuntimeDriverData->m_strName ); if( nActualIndex != CB_ERR ) { m_DriversCombo.SetItemData( nActualIndex, nCrtDriver ); } } } delete [] pbAlreadyInCombo; // // Restore the old current selection in the combo // nComboItemCount = m_DriversCombo.GetCount(); for( nCrtItemIndex = 0; nCrtItemIndex < nComboItemCount; nCrtItemIndex++ ) { m_DriversCombo.GetLBText( nCrtItemIndex, strDriverName ); if( strDriverName.CompareNoCase( strCurrentDriverName ) == 0 ) { nCrtSelectedItem = nCrtItemIndex; break; } } m_DriversCombo.SetCurSel( nCrtSelectedItem ); OnSelendokDriverCombo(); } Done: NOTHING; } ///////////////////////////////////////////////////////////// VOID CDriverCountersPage::RefreshInfo() { if( UpdateData( FALSE ) ) { // // Refresh the combo content - this will also // refresh the counters list // RefreshCombo(); } } ///////////////////////////////////////////////////////////// VOID CDriverCountersPage::GetCurrentSelDriverName( CString &strName ) { INT nCrtSel; nCrtSel = m_DriversCombo.GetCurSel(); if( CB_ERR != nCrtSel ) { m_DriversCombo.GetLBText( nCrtSel, strName ); } else { strName.Empty(); } } ///////////////////////////////////////////////////////////// CRuntimeDriverData *CDriverCountersPage::GetCurrentDrvRuntimeData() { INT nCrtComboSelection; INT_PTR nCrtDriverIndex; CRuntimeDriverData *pRuntimeDriverData; pRuntimeDriverData = NULL; nCrtDriverIndex = -1; nCrtComboSelection = m_DriversCombo.GetCurSel(); if( nCrtComboSelection != CB_ERR ) { nCrtDriverIndex = m_DriversCombo.GetItemData( nCrtComboSelection ); if( nCrtDriverIndex >= 0 && nCrtDriverIndex < m_RuntimeVerifierData.m_RuntimeDriverDataArray.GetSize() ) { pRuntimeDriverData = m_RuntimeVerifierData.m_RuntimeDriverDataArray.GetAt( nCrtDriverIndex ); ASSERT_VALID( pRuntimeDriverData ); } } return pRuntimeDriverData; } ///////////////////////////////////////////////////////////// VOID CDriverCountersPage::SortTheList() { if( 0 != m_nSortColumnIndex ) { // // Sort by counter value - this is probably not very useful // but we are providing it to be consistent with all // the lists being sortable by any column // m_CountersList.SortItems( CounterValueCmpFunc, (LPARAM)this ); } else { // // Sort by driver name // m_CountersList.SortItems( CounterNameCmpFunc, (LPARAM)this ); } } ///////////////////////////////////////////////////////////// int CALLBACK CDriverCountersPage::CounterValueCmpFunc( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { SIZE_T size1; SIZE_T size2; int nCmpRez = 0; CDriverCountersPage *pThis = (CDriverCountersPage *)lParamSort; ASSERT_VALID( pThis ); size1 = pThis->GetCounterValue( (INT) lParam1 ); size2 = pThis->GetCounterValue( (INT) lParam2 ); if( size1 > size2 ) { nCmpRez = 1; } else { if( size1 < size2 ) { nCmpRez = -1; } } if( FALSE != pThis->m_bAscendSortValue ) { nCmpRez *= -1; } return nCmpRez; } ///////////////////////////////////////////////////////////// int CALLBACK CDriverCountersPage::CounterNameCmpFunc( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { int nCmpRez = 0; BOOL bSuccess; TCHAR szCounterName1[ _MAX_PATH ]; TCHAR szCounterName2[ _MAX_PATH ]; CDriverCountersPage *pThis = (CDriverCountersPage *)lParamSort; ASSERT_VALID( pThis ); // // Get the first counter name // bSuccess = pThis->GetCounterName( lParam1, szCounterName1, ARRAY_LENGTH( szCounterName1 ) ); if( FALSE == bSuccess ) { goto Done; } // // Get the second counter name // bSuccess = pThis->GetCounterName( lParam2, szCounterName2, ARRAY_LENGTH( szCounterName2 ) ); if( FALSE == bSuccess ) { goto Done; } // // Compare the names // nCmpRez = _tcsicmp( szCounterName1, szCounterName2 ); if( FALSE != pThis->m_bAscendSortName ) { nCmpRez *= -1; } Done: return nCmpRez; } ///////////////////////////////////////////////////////////// // CDriverCountersPage message handlers BOOL CDriverCountersPage::OnInitDialog() { CPropertyPage::OnInitDialog(); // // Setup the settings bits list // m_CountersList.SetExtendedStyle( LVS_EX_FULLROWSELECT | m_CountersList.GetExtendedStyle() ); m_CountersList.SetBkColor( ::GetSysColor( COLOR_3DFACE ) ); m_CountersList.SetTextBkColor( ::GetSysColor( COLOR_3DFACE ) ); SetupListHeader(); FillTheList(); SortTheList(); RefreshCombo(); VrfSetWindowText( m_NextDescription, IDS_DCNT_PAGE_NEXT_DESCR ); VERIFY( m_uTimerHandler = SetTimer( REFRESH_TIMER_ID, 5000, NULL ) ); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } ///////////////////////////////////////////////////////////// VOID CDriverCountersPage::OnTimer(UINT nIDEvent) { if( nIDEvent == REFRESH_TIMER_ID ) { ASSERT_VALID( m_pParentSheet ); if( m_pParentSheet->GetActivePage() == this ) { // // Refresh the displayed data // RefreshInfo(); } } CPropertyPage::OnTimer(nIDEvent); } ///////////////////////////////////////////////////////////////////////////// BOOL CDriverCountersPage::OnSetActive() { ASSERT_VALID( m_pParentSheet ); m_pParentSheet->SetWizardButtons( PSWIZB_BACK | PSWIZB_FINISH ); return CVerifierPropertyPage::OnSetActive(); } ///////////////////////////////////////////////////////////// void CDriverCountersPage::OnSelendokDriverCombo() { RefreshTheList(); } ///////////////////////////////////////////////////////////// void CDriverCountersPage::OnColumnclickPerdrvcList(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; if( 0 != pNMListView->iSubItem ) { // // Clicked on the counter value column // if( m_nSortColumnIndex == pNMListView->iSubItem ) { // // Change the current ascend/descend order for this column // m_bAscendSortValue = !m_bAscendSortValue; } } else { // // Clicked on the counter name column // if( m_nSortColumnIndex == pNMListView->iSubItem ) { // // Change the current ascend/descend order for this column // m_bAscendSortName = !m_bAscendSortName; } } m_nSortColumnIndex = pNMListView->iSubItem; SortTheList(); *pResult = 0; } ///////////////////////////////////////////////////////////// LONG CDriverCountersPage::OnHelp( WPARAM wParam, LPARAM lParam ) { LONG lResult = 0; LPHELPINFO lpHelpInfo = (LPHELPINFO)lParam; ::WinHelp( (HWND) lpHelpInfo->hItemHandle, g_szVerifierHelpFile, HELP_WM_HELP, (DWORD_PTR) MyHelpIds ); return lResult; } ///////////////////////////////////////////////////////////////////////////// void CDriverCountersPage::OnContextMenu(CWnd* pWnd, CPoint point) { ::WinHelp( pWnd->m_hWnd, g_szVerifierHelpFile, HELP_CONTEXTMENU, (DWORD_PTR) MyHelpIds ); }