Leaked source code of windows server 2003
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.

291 lines
8.8 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. if (NULL == pIndex) return FALSE;
  44. if (CFlexArray::no_error != m_array.Add( pIndex )) return FALSE;
  45. bRet = TRUE;
  46. }
  47. return bRet;
  48. }
  49. void CIndexTable::Empty()
  50. {
  51. int nSize = m_array.Size();
  52. for ( int nIndex = 0; nIndex < nSize; nIndex++ )
  53. {
  54. int* pIndex = (int*)m_array.GetAt( nIndex );
  55. delete pIndex;
  56. }
  57. m_array.Empty();
  58. }
  59. //////////////////////////////////////////////////////////////////////
  60. // Construction/Destruction
  61. //////////////////////////////////////////////////////////////////////
  62. CPerfLibSchema::CPerfLibSchema( WCHAR* pwcsServiceName,
  63. CLocaleCache* pLocaleCache ):
  64. m_pLocaleCache(pLocaleCache),
  65. m_dwFirstCtr(2),
  66. m_dwLastCtr(CPerfNameDb::GetSystemReservedHigh())
  67. {
  68. if ( NULL != m_pLocaleCache )
  69. m_pLocaleCache->AddRef();
  70. memset( m_apClassList, NULL, WMI_ADAP_NUM_TYPES * sizeof( CPerfClassList* ) );
  71. m_wstrServiceName = pwcsServiceName;
  72. }
  73. CPerfLibSchema::~CPerfLibSchema()
  74. {
  75. if ( NULL != m_pLocaleCache )
  76. m_pLocaleCache->Release();
  77. for ( DWORD dwType = 0; dwType < WMI_ADAP_NUM_TYPES; dwType++ )
  78. {
  79. if ( NULL != m_apClassList[ dwType ] )
  80. m_apClassList[ dwType ]->Release();
  81. m_aIndexTable[ dwType ].Empty();
  82. }
  83. }
  84. HRESULT CPerfLibSchema::Initialize( BOOL bDelta, DWORD * pLoadStatus)
  85. {
  86. HRESULT hr = WBEM_S_NO_ERROR;
  87. CAdapPerfLib* pPerfLib = NULL;
  88. BOOL bInactive = TRUE;
  89. try
  90. {
  91. // Create and initialize the perflib wrapper
  92. // =========================================
  93. pPerfLib = new CAdapPerfLib( m_wstrServiceName,pLoadStatus );
  94. CAdapReleaseMe rmPerfLib( pPerfLib );
  95. if ( NULL != pPerfLib )
  96. {
  97. if ( bDelta && pPerfLib->CheckStatus( ADAP_PERFLIB_PREVIOUSLY_PROCESSED ) )
  98. {
  99. hr = WBEM_S_ALREADY_EXISTS;
  100. }
  101. else if ( pPerfLib->IsOK() )
  102. {
  103. m_dwFirstCtr = pPerfLib->GetFirstCtr();
  104. m_dwLastCtr = pPerfLib->GetLastCtr();
  105. //
  106. // errors from the perflib!Open call are returned here
  107. //
  108. hr = pPerfLib->Initialize();
  109. // Get the perflib blobs
  110. // =====================
  111. if ( SUCCEEDED ( hr ) )
  112. {
  113. m_aBlob[COSTLY].SetCostly( TRUE );
  114. for ( int nBlob = GLOBAL; SUCCEEDED ( hr ) && nBlob < NUMBLOBS; nBlob ++ )
  115. {
  116. hr = pPerfLib->GetBlob( m_aBlob[nBlob].GetPerfBlockPtrPtr(),
  117. m_aBlob[nBlob].GetSizePtr(),
  118. m_aBlob[nBlob].GetNumObjectsPtr(),
  119. m_aBlob[nBlob].GetCostly() );
  120. if (FAILED(hr))
  121. {
  122. ERRORTRACE((LOG_WMIADAP,"Collect for service %S for %s counters failed\n",(WCHAR *)m_wstrServiceName,m_aBlob[nBlob].GetCostly()?"Costly":"Global"));
  123. }
  124. // check the return status hr
  125. if (FAILED(hr) &&
  126. (!pPerfLib->IsCollectOK()) &&
  127. pLoadStatus )
  128. {
  129. (*pLoadStatus) |= EX_STATUS_COLLECTFAIL;
  130. }
  131. // Perflib is inactive if ALL blobs are 0 length
  132. // =============================================
  133. bInactive = bInactive && ( 0 == m_aBlob[nBlob].GetSize() );
  134. }
  135. if ( bInactive )
  136. {
  137. pPerfLib->SetStatus( ADAP_PERFLIB_IS_INACTIVE );
  138. hr = WBEM_E_FAILED;
  139. ERRORTRACE((LOG_WMIADAP,"Collect for service %S returned 0-Size BLOBs\n",(WCHAR *)m_wstrServiceName));
  140. }
  141. pPerfLib->Close();
  142. }
  143. }
  144. else
  145. {
  146. hr = WBEM_E_FAILED;
  147. }
  148. }
  149. else
  150. {
  151. hr = WBEM_E_OUT_OF_MEMORY;
  152. }
  153. // store the final status in the registry in the EndProcessingStatus
  154. if ( NULL != pPerfLib )
  155. {
  156. pPerfLib->Cleanup();
  157. }
  158. }
  159. catch(...)
  160. {
  161. hr = WBEM_E_OUT_OF_MEMORY;
  162. }
  163. return hr;
  164. }
  165. HRESULT CPerfLibSchema::GetClassList( DWORD dwType, CClassList** ppClassList )
  166. {
  167. HRESULT hr = WBEM_S_NO_ERROR;
  168. // If the class list does not already exist, then create it
  169. // ========================================================
  170. if ( NULL == m_apClassList[ dwType ] )
  171. {
  172. hr = CreateClassList( dwType );
  173. }
  174. // Set pass back the pointer
  175. // =========================
  176. if ( SUCCEEDED( hr ) )
  177. {
  178. *ppClassList = m_apClassList[ dwType ];
  179. if ( NULL != *ppClassList )
  180. (*ppClassList)->AddRef();
  181. }
  182. return hr;
  183. }
  184. HRESULT CPerfLibSchema::CreateClassList( DWORD dwType )
  185. {
  186. HRESULT hr = WBEM_S_NO_ERROR;
  187. m_apClassList[ dwType ] = new CPerfClassList( m_pLocaleCache, m_wstrServiceName );
  188. if ( NULL == m_apClassList[ dwType ] )
  189. {
  190. hr = WBEM_E_OUT_OF_MEMORY;
  191. }
  192. // Cycle through all perfomance blobs (Global & Costly)
  193. // ====================================================
  194. if ( SUCCEEDED( hr ) )
  195. {
  196. for ( DWORD dwBlob = GLOBAL; dwBlob < NUMBLOBS; dwBlob++ )
  197. {
  198. PERF_OBJECT_TYPE* pCurrentObject = NULL;
  199. CPerfLibBlobDefn* pBlobDefn = &m_aBlob[dwBlob];
  200. DWORD dwNumObjects = pBlobDefn->GetNumObjects();
  201. for ( DWORD dwCtr = 0; SUCCEEDED( hr ) && dwCtr < dwNumObjects; dwCtr++ )
  202. {
  203. // Get the current object
  204. // ======================
  205. if ( 0 == dwCtr )
  206. {
  207. pCurrentObject = pBlobDefn->GetBlob();
  208. }
  209. else
  210. {
  211. LPBYTE pbData = (LPBYTE) pCurrentObject;
  212. pbData += pCurrentObject->TotalByteLength;
  213. pCurrentObject = (PERF_OBJECT_TYPE*) pbData;
  214. }
  215. if (m_dwFirstCtr <= pCurrentObject->ObjectNameTitleIndex &&
  216. pCurrentObject->ObjectNameTitleIndex <= m_dwLastCtr)
  217. {
  218. // To ensure uniqueness, we manage a list of processed indicies
  219. // ============================================================
  220. if ( m_aIndexTable[dwType].Add( pCurrentObject->ObjectNameTitleIndex ) )
  221. {
  222. hr = m_apClassList[dwType]->AddPerfObject( pCurrentObject, dwType, pBlobDefn->GetCostly() );
  223. }
  224. }
  225. else
  226. {
  227. ERRORTRACE((LOG_WMIADAP,"Skipping Object of index %d of service %S "
  228. " because index does not belong to the range %d - %d "
  229. " assigned to the service by LodCtr\n",
  230. pCurrentObject->ObjectNameTitleIndex,
  231. (WCHAR *)m_wstrServiceName,
  232. m_dwFirstCtr,
  233. m_dwLastCtr));
  234. }
  235. }
  236. }
  237. }
  238. return hr;
  239. }