//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1993 - 2000. // // File: perfobj.cxx // // Contents: Performance Data Object // // Classes : CPerfMon, PPerfCounter, // CPerfCount, CPerfTime, // CReadUserPerfData // // History: 23-March-94 t-joshh Created // //---------------------------------------------------------------------------- #include #pragma hdrstop #include #include #include "perfobj2.hxx" extern CI_DATA_DEFINITION CIDataDefinition; extern FILTER_DATA_DEFINITION FILTERDataDefinition; #define FILTERTOTALCOUNTER ((int) FILTERDataDefinition.FILTERObjectType.NumCounters) #define CITOTALCOUNTER ((int) CIDataDefinition.CIObjectType.NumCounters) // // Total size occupied by the counters // #define TOTALCOUNTERSIZE ( (FILTERTOTALCOUNTER + CITOTALCOUNTER ) * sizeof(DWORD) ) //+--------------------------------------------------------------------------- // // Function : CReadUserPerfData::CReadUserPerfData // // Purpose : Constructor // // Arguments : none // // History : 23-March-94 t-joshh Created // //---------------------------------------------------------------------------- CReadUserPerfData::CReadUserPerfData() : _cInstances( 0 ), _finitOK( FALSE ), _cCounters( 0 ), _pSeqNo( 0 ), _cMaxCats( 0 ), _cbPerfHeader( 0 ) { } //+--------------------------------------------------------------------------- // // Function : CReadUserPerfData::Finish // // Purpose : Close and clean up the handles // // Arguments : none // // History : 23-March-94 t-joshh Created // // Note: Must execute when done with getting the data // //---------------------------------------------------------------------------- void CReadUserPerfData::Finish() { CleanupForReInit(); _xSharedMemObj.Free(); } //+--------------------------------------------------------------------------- // // Member: CReadUserPerfData::CleanupForReInit // // Synopsis: Cleans up the data structures in preparation for a // re-initialization. Only the data which needs to be re-read // and initialized is thrown away. The Shared memory object is // NOT deleted because it is system-wide state and there is no // need to throw it away. // // History: 6-21-96 srikants Created // //---------------------------------------------------------------------------- void CReadUserPerfData::CleanupForReInit() { } //+--------------------------------------------------------------------------- // // Function : CReadUserPerfData::InitforRead // // Purpose : Initialize to be ready for reading the perf. data // // Arguments : none // // History : 23-March-94 t-joshh Created // // Note: Must be executed before any operations // // Return : TRUE -- success, FALSE -- failed // //---------------------------------------------------------------------------- BOOL CReadUserPerfData::InitForRead() { if ( _xSharedMemObj.IsNull() ) { ULONG cbCatBitfield, cbSharedMem; ComputeCIPerfmonVars( _cMaxCats, cbCatBitfield, _cbPerfHeader, cbSharedMem ); // // Open the shared memory // _xSharedMemObj.Set( new CNamedSharedMem() ); BOOL fOK = _xSharedMemObj->OpenForRead( CI_PERF_MEM_NAME ); if ( !fOK ) return FALSE; _pSeqNo = (UINT *) (((BYTE *)_xSharedMemObj->Get())+sizeof(int) + cbCatBitfield); } if ( _finitOK ) CleanupForReInit(); _finitOK = FALSE; if ( _xSharedMemObj->Ok() ) { _cInstances = *((int *)_xSharedMemObj->Get()); PerfDebugOut(( DEB_ITRACE, "!!! Reader : No. of Instance : %d\n", _cInstances )); _cCounters = FILTERTOTALCOUNTER; _finitOK = TRUE; return TRUE; } return FALSE; } //InitForRead //+--------------------------------------------------------------------------- // // Function : CReadUserPerfData::NumberOfInstance // // Purpose : Return the number of existing instances // // Arguments : none // // History : 23-March-94 t-joshh Created // //---------------------------------------------------------------------------- int CReadUserPerfData::NumberOfInstance() { return _cInstances; } UINT CReadUserPerfData::GetSeqNo() const { return _pSeqNo ? *_pSeqNo : 0; } //+--------------------------------------------------------------------------- // // Function : CReadUserPerfData::GetInstanceName // // Purpose : Return the specified instance's name // // Arguments : [iWhichOne] -- which instance // // History : 23-March-94 t-joshh Created // //---------------------------------------------------------------------------- WCHAR * CReadUserPerfData::GetInstanceName ( int iWhichOne ) { if ( !_xSharedMemObj.IsNull() && _xSharedMemObj->Ok() ) { // // Find the corresponding slot in the shared memory // BYTE * pbBitfield = (BYTE *) _xSharedMemObj->Get() + sizeof(int); CBitfield bits( pbBitfield ); int i = 0; for ( int j = 0; j <= iWhichOne && i < (int) _cMaxCats; i++ ) { if ( bits.IsBitSet( i ) ) j++; } iWhichOne = i - 1; ULONG ByteToSkip = _cbPerfHeader + ( iWhichOne * cbPerfCatalogSlot ) + sizeof(int); return( (WCHAR *)((BYTE *)_xSharedMemObj->Get() + ByteToSkip) ); } return 0; } //GetInstanceName //+--------------------------------------------------------------------------- // // Function : CReadUserPerfData::GetCounterValue // // Purpose : Return the value of the specified counter // // Arguments : [iWhichInstance] -- which instance of object does the // counter belong to // [iWhichCounter] -- which counter // // History : 23-March-94 t-joshh Created // //---------------------------------------------------------------------------- DWORD CReadUserPerfData::GetCounterValue( int iWhichInstance, int iWhichCounter ) { if ( !_xSharedMemObj.IsNull() && _xSharedMemObj->Ok() ) { // // Find the corresponding slot // BYTE * pbBitfield = (BYTE *) _xSharedMemObj->Get() + sizeof(int); CBitfield bits( pbBitfield ); int i = 0; for ( int j = 0; j <= iWhichInstance && i < (int) _cMaxCats; i++ ) { if ( bits.IsBitSet( i ) ) j++; } int iWhichSlot = i - 1; PerfDebugOut(( DEB_ITRACE, "Choose slot %i\n", iWhichSlot)); ULONG ByteToSkip = _cbPerfHeader + ( iWhichSlot * cbPerfCatalogSlot ) + sizeof(int) + ( CI_PERF_MAX_CATALOG_LEN * sizeof(WCHAR) ) // Name of the instance + ( iWhichCounter * sizeof(DWORD) ); return *(DWORD *)((BYTE *)_xSharedMemObj->Get() + ByteToSkip); } return 0; } //GetCounterValue //+--------------------------------------------------------------------------- // // Function : CReadKernelPerfData::CReadKernelPerfData // // Purpose : Constructor // // Arguments : none // // History : 23-March-94 t-joshh Created // //---------------------------------------------------------------------------- CReadKernelPerfData::CReadKernelPerfData() : _pSeqNo(0), _cInstance( 0 ), _finitOK( FALSE ), _cCounters( 0 ), _cMaxCats( 0 ), _cbPerfHeader( 0 ), _cbSharedMem( 0 ) { } UINT CReadKernelPerfData::GetSeqNo() const { return _pSeqNo ? *_pSeqNo : 0; } //+--------------------------------------------------------------------------- // // Function : CReadKernelPerfData::Finish // // Purpose : Close and clean up the handles // // Arguments : none // // History : 23-March-94 t-joshh Created // // Note: Must execute when done with getting the data // //---------------------------------------------------------------------------- void CReadKernelPerfData::Finish() { CleanupForReInit(); _xSharedMemory.Free(); _xMemory.Free(); _xCatalogs.Free(); _xCatalogMem.Free(); } //+--------------------------------------------------------------------------- // // Function : CReadKernelPerfData::FindDownlevelDrives // // Purpose : Find the remote drive // // History : 23-Mar-94 t-joshh Created // 31-Jan-96 KyleP Look for all downlevel drives // //---------------------------------------------------------------------------- void CReadKernelPerfData::FindDownlevelDrives() { if ( _xSharedMemory->Ok() ) { // // Get active drive count and active bit array. // int cCount = * (int *) _xSharedMemory->Get(); BYTE * pbBitfield = (BYTE *) _xSharedMemory->Get() + sizeof(int); CBitfield bits( pbBitfield ); // // Loop through looking for drives. // for (int i = 0; cCount > 0 ; cCount--, i++) { for (; i < (int) _cMaxCats && !bits.IsBitSet( i ); i++) {} if ( (int) _cMaxCats == i ) { PerfDebugOut(( DEB_ITRACE, "!!! Error in the empty slot\n")); return; } else { // // Find offset of drive name in shared memory buffer. // ULONG oCounters = _cbPerfHeader + (i * cbPerfCatalogSlot) + sizeof(int); WCHAR * wszTmp = (WCHAR *) ((BYTE *) _xSharedMemory->Get() + oCounters); // // Make sure this isn't already in the list // for ( int j = 0; j < cCount; j++ ) { if ( 0 != _xCatalogs[j] && wcscmp( _xCatalogs[j], wszTmp ) == 0 ) break; } // // Add downlevel drive. // if ( j == cCount ) { PerfDebugOut(( DEB_ITRACE, "!!! Kernel Reader : Downlevel Drive %ws\n", wszTmp )); // // Find offset of first counter. // oCounters += ((sizeof(DWORD) * NUM_KERNEL_AND_USER_COUNTER) + (CI_PERF_MAX_CATALOG_LEN * sizeof(WCHAR))); _xCatalogMem[_cInstance] = (void *) ((BYTE *) _xSharedMemory->Get() + oCounters); _xCatalogs[_cInstance] = new WCHAR[wcslen(wszTmp) + 1]; wcscpy(_xCatalogs[_cInstance++], wszTmp); } } } } } //FindDownlevelDrives //+--------------------------------------------------------------------------- // // Member: CReadKernelPerfData::CleanupForReInit // // Synopsis: Cleans up the state and makes it ready for re-initialization. // // History: 6-21-96 srikants Created // // Notes: // //---------------------------------------------------------------------------- void CReadKernelPerfData::CleanupForReInit() { for ( int i = 0; i < _cInstance; i++) { delete _xCatalogs[i]; _xCatalogs[i] = 0; } _cInstance = 0; } //+--------------------------------------------------------------------------- // // Function : CReadKernelPerfData::InitForRead // // Purpose : Initialize to be ready for reading the perf. data // // Arguments : none // // History : 23-Mar-94 t-joshh Created // 31-Jan-96 KyleP Improvements for downlevel CI // // Note: Must be executed before any operations // //---------------------------------------------------------------------------- BOOL CReadKernelPerfData::InitForRead() { if ( _xSharedMemory.IsNull() ) { ULONG cbCatBitfield; ComputeCIPerfmonVars( _cMaxCats, cbCatBitfield, _cbPerfHeader, _cbSharedMem ); // // Open the shared memory // _xSharedMemory.Set( new CNamedSharedMem() ); BOOL fOK = _xSharedMemory->OpenForRead( CI_PERF_MEM_NAME ); if ( !fOK ) return FALSE; _pSeqNo = (UINT *) (((BYTE *)_xSharedMemory->Get())+sizeof(int) + cbCatBitfield); } // // Initialize the drive list // if ( _finitOK ) CleanupForReInit(); _finitOK = FALSE; if ( _xCatalogs.IsNull() ) _xCatalogs.Init( _cMaxCats ); if ( _xCatalogMem.IsNull() ) _xCatalogMem.Init( _cMaxCats ); for ( unsigned j = 0; j < _cMaxCats; j++) { _xCatalogs[j] = 0; _xCatalogMem[j] = 0; } FindDownlevelDrives(); _cCounters = CITOTALCOUNTER; _finitOK = TRUE; return TRUE; PerfDebugOut(( DEB_ITRACE, "!!! Kernel Reader : Initialize finish\n")); } //InitForRead //+--------------------------------------------------------------------------- // // Function : CReadKernelPerfData::NumberOfInstance // // Purpose : Return the number of existing instances // // Arguments : none // // History : 23-March-94 t-joshh Created // //---------------------------------------------------------------------------- int CReadKernelPerfData::NumberOfInstance() { return _cInstance; } //+--------------------------------------------------------------------------- // // Function : CReadKernelPerfData::GetInstanceName // // Purpose : Return the specified instance's name // // Arguments : [iWhichOne] -- which instance // // History : 23-March-94 t-joshh Created // //---------------------------------------------------------------------------- WCHAR * CReadKernelPerfData::GetInstanceName ( int iWhichOne ) { return _xCatalogs[iWhichOne]; } //+--------------------------------------------------------------------------- // // Function : CReadKernelPerfData::Refresh // // Purpose : Retrieve the most updated data // // Arguments : [iWhichInstance] -- which instance of object does the // counter belong to // // History : 23-March-94 t-joshh Created // //---------------------------------------------------------------------------- BOOL CReadKernelPerfData::Refresh( int iWhichInstance ) { // // the instance is either downlevel drive or remote drive // Win4Assert( 0 != _cbSharedMem ); if ( _xMemory.IsNull() ) _xMemory.Init( _cbSharedMem ); ULONG oCounters = _cbPerfHeader + sizeof(int) + (CI_PERF_MAX_CATALOG_LEN * sizeof WCHAR); if ( _xCatalogMem.IsNull() ) _xCatalogMem.Init( _cMaxCats ); void * pvTmp = _xCatalogMem[iWhichInstance]; for ( int j = 0; j < CITOTALCOUNTER; j++) { *(DWORD *)(_xMemory.GetPointer() + oCounters) = *(DWORD *)pvTmp; oCounters += sizeof(DWORD); pvTmp = (void *)((BYTE *)pvTmp + sizeof(DWORD)); } return TRUE; } //Refresh //+--------------------------------------------------------------------------- // // Function : CReadKernelPerfData::GetCounterValue // // Purpose : Return the value of the specified counter // // Arguments : [iWhichCounter] -- which counter // // History : 23-March-94 t-joshh Created // //---------------------------------------------------------------------------- DWORD CReadKernelPerfData::GetCounterValue( int iWhichCounter ) { if ( !_xMemory.IsNull() ) { ULONG ByteToSkip = _cbPerfHeader + sizeof(int) + (CI_PERF_MAX_CATALOG_LEN * sizeof WCHAR) // Name of the instance + ( iWhichCounter * sizeof(DWORD) ); return *(DWORD *)(_xMemory.GetPointer() + ByteToSkip); } return 0; } //GetCounterValue