Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

264 lines
6.3 KiB

  1. /*++
  2. Copyright (C) 1999-2001 Microsoft Corporation
  3. Module Name:
  4. PERFLIBSCHEMA.CPP
  5. Abstract:
  6. implementation of the CPerfLibSchema class.
  7. History:
  8. --*/
  9. #include "precomp.h"
  10. #include <stdio.h>
  11. #include <wtypes.h>
  12. #include <oleauto.h>
  13. #include <winmgmtr.h>
  14. #include "PerfLibSchema.h"
  15. #include "AdapUtil.h"
  16. ////////////////////////////////////////////////////////////////////////////////
  17. //
  18. // CIndexTable
  19. //
  20. // This is a look aside table used for processing the perflib data blob. It
  21. // guarentees that no duplicate indicies will be allowed to be added to the
  22. // table.
  23. //
  24. ////////////////////////////////////////////////////////////////////////////////
  25. int CIndexTable::Locate( int nIndex )
  26. {
  27. int nRet = not_found;
  28. int nSize = m_array.Size();
  29. for ( int n = 0; ( not_found == nRet ) && ( n < nSize ); n++ )
  30. {
  31. int* pIndex = (int*)m_array.GetAt( n );
  32. if ( *pIndex == nIndex )
  33. nRet = n;
  34. }
  35. return nRet;
  36. }
  37. BOOL CIndexTable::Add( int nIndex )
  38. {
  39. BOOL bRet = FALSE;
  40. if ( not_found == Locate( nIndex ) )
  41. {
  42. int* pIndex = new int( nIndex );
  43. m_array.Add( pIndex );
  44. bRet = TRUE;
  45. }
  46. return bRet;
  47. }
  48. void CIndexTable::Empty()
  49. {
  50. int nSize = m_array.Size();
  51. for ( int nIndex = 0; nIndex < nSize; nIndex++ )
  52. {
  53. int* pIndex = (int*)m_array.GetAt( nIndex );
  54. delete pIndex;
  55. }
  56. m_array.Empty();
  57. }
  58. //////////////////////////////////////////////////////////////////////
  59. // Construction/Destruction
  60. //////////////////////////////////////////////////////////////////////
  61. CPerfLibSchema::CPerfLibSchema( WCHAR* pwcsServiceName, CLocaleCache* pLocaleCache )
  62. : m_pLocaleCache( pLocaleCache )
  63. {
  64. if ( NULL != m_pLocaleCache )
  65. m_pLocaleCache->AddRef();
  66. memset( m_apClassList, NULL, WMI_ADAP_NUM_TYPES * sizeof( CPerfClassList* ) );
  67. m_wstrServiceName = pwcsServiceName;
  68. }
  69. CPerfLibSchema::~CPerfLibSchema()
  70. {
  71. if ( NULL != m_pLocaleCache )
  72. m_pLocaleCache->Release();
  73. for ( DWORD dwType = 0; dwType < WMI_ADAP_NUM_TYPES; dwType++ )
  74. {
  75. if ( NULL != m_apClassList[ dwType ] )
  76. m_apClassList[ dwType ]->Release();
  77. m_aIndexTable[ dwType ].Empty();
  78. }
  79. }
  80. HRESULT CPerfLibSchema::Initialize( BOOL bDelta, DWORD * pLoadStatus )
  81. {
  82. HRESULT hr = WBEM_S_NO_ERROR;
  83. CAdapPerfLib* pPerfLib = NULL;
  84. BOOL bInactive = TRUE;
  85. try
  86. {
  87. // Create and initialize the perflib wrapper
  88. // =========================================
  89. pPerfLib = new CAdapPerfLib( m_wstrServiceName,pLoadStatus );
  90. CAdapReleaseMe rmPerfLib( pPerfLib );
  91. if ( NULL != pPerfLib )
  92. {
  93. if ( bDelta && pPerfLib->CheckStatus( ADAP_PERFLIB_PREVIOUSLY_PROCESSED ) )
  94. {
  95. hr = WBEM_S_ALREADY_EXISTS;
  96. }
  97. else if ( pPerfLib->IsOK() )
  98. {
  99. //
  100. // errors from the perflib!Open call are returned here
  101. //
  102. hr = pPerfLib->Initialize();
  103. // Get the perflib blobs
  104. // =====================
  105. if ( SUCCEEDED ( hr ) )
  106. {
  107. m_aBlob[COSTLY].SetCostly( TRUE );
  108. for ( int nBlob = GLOBAL; SUCCEEDED ( hr ) && nBlob < NUMBLOBS; nBlob ++ )
  109. {
  110. hr = pPerfLib->GetBlob( m_aBlob[nBlob].GetPerfBlockPtrPtr(),
  111. m_aBlob[nBlob].GetSizePtr(),
  112. m_aBlob[nBlob].GetNumObjectsPtr(),
  113. m_aBlob[nBlob].GetCostly() );
  114. // check the return status hr
  115. if (FAILED(hr) &&
  116. (!pPerfLib->IsCollectOK()) &&
  117. pLoadStatus ){
  118. (*pLoadStatus) |= EX_STATUS_COLLECTFAIL;
  119. }
  120. // Perflib is inactive if ALL blobs are 0 length
  121. // =============================================
  122. bInactive = bInactive && ( 0 == m_aBlob[nBlob].GetSize() );
  123. }
  124. if ( bInactive )
  125. {
  126. pPerfLib->SetStatus( ADAP_PERFLIB_IS_INACTIVE );
  127. hr = WBEM_E_FAILED;
  128. }
  129. pPerfLib->Close();
  130. }
  131. }
  132. else
  133. {
  134. hr = WBEM_E_FAILED;
  135. }
  136. }
  137. else
  138. {
  139. hr = WBEM_E_OUT_OF_MEMORY;
  140. }
  141. // store the final status in the registry in the EndProcessingStatus
  142. if ( NULL != pPerfLib )
  143. {
  144. pPerfLib->Cleanup();
  145. }
  146. }
  147. catch(...)
  148. {
  149. hr = WBEM_E_OUT_OF_MEMORY;
  150. }
  151. return hr;
  152. }
  153. HRESULT CPerfLibSchema::GetClassList( DWORD dwType, CClassList** ppClassList )
  154. {
  155. HRESULT hr = WBEM_S_NO_ERROR;
  156. // If the class list does not already exist, then create it
  157. // ========================================================
  158. if ( NULL == m_apClassList[ dwType ] )
  159. {
  160. hr = CreateClassList( dwType );
  161. }
  162. // Set pass back the pointer
  163. // =========================
  164. if ( SUCCEEDED( hr ) )
  165. {
  166. *ppClassList = m_apClassList[ dwType ];
  167. if ( NULL != *ppClassList )
  168. (*ppClassList)->AddRef();
  169. }
  170. return hr;
  171. }
  172. HRESULT CPerfLibSchema::CreateClassList( DWORD dwType )
  173. {
  174. HRESULT hr = WBEM_S_NO_ERROR;
  175. m_apClassList[ dwType ] = new CPerfClassList( m_pLocaleCache, m_wstrServiceName );
  176. if ( NULL == m_apClassList[ dwType ] )
  177. {
  178. hr = WBEM_E_OUT_OF_MEMORY;
  179. }
  180. // Cycle through all perfomance blobs (Global & Costly)
  181. // ====================================================
  182. if ( SUCCEEDED( hr ) )
  183. {
  184. for ( DWORD dwBlob = GLOBAL; dwBlob < NUMBLOBS; dwBlob++ )
  185. {
  186. PERF_OBJECT_TYPE* pCurrentObject = NULL;
  187. CPerfLibBlobDefn* pBlobDefn = &m_aBlob[dwBlob];
  188. DWORD dwNumObjects = pBlobDefn->GetNumObjects();
  189. for ( DWORD dwCtr = 0; SUCCEEDED( hr ) && dwCtr < dwNumObjects; dwCtr++ )
  190. {
  191. // Get the current object
  192. // ======================
  193. if ( 0 == dwCtr )
  194. {
  195. pCurrentObject = pBlobDefn->GetBlob();
  196. }
  197. else
  198. {
  199. LPBYTE pbData = (LPBYTE) pCurrentObject;
  200. pbData += pCurrentObject->TotalByteLength;
  201. pCurrentObject = (PERF_OBJECT_TYPE*) pbData;
  202. }
  203. // To ensure uniqueness, we manage a list of processed indicies
  204. // ============================================================
  205. if ( m_aIndexTable[dwType].Add( pCurrentObject->ObjectNameTitleIndex ) )
  206. {
  207. hr = m_apClassList[dwType]->AddPerfObject( pCurrentObject, dwType, pBlobDefn->GetCostly() );
  208. }
  209. }
  210. }
  211. }
  212. return hr;
  213. }