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.

442 lines
12 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. History:
  6. --*/
  7. #define _WIN32_WINNT 0x0400
  8. #define UNICODE
  9. #include "precomp.h"
  10. #include "RawCooker.h"
  11. #include "WMIObjCooker.h"
  12. #include "Refresher.h"
  13. IWbemServices* g_pNameSpace = NULL; // A WMI namespace pointer
  14. IWbemRefresher* g_pRefresher = NULL;
  15. IWbemConfigureRefresher* g_pConfig = NULL;
  16. IWbemClassObject* g_pCookedClass = NULL;
  17. IWbemObjectAccess* g_pCookingAccess = NULL;
  18. #define WMI_NAMESPACE L"root\\default"
  19. #define WMI_RAWCLASS L"Win32_BasicHiPerf"
  20. #define WMI_COOKEDCLASS L"Win32_CookingHiPerf"
  21. #define WMI_KEY_PROP L"ID"
  22. #define WMI_PROPERTY L"Counter1"
  23. #define WMI_NO_OUTPUT
  24. /*
  25. typedef struct tagCookingInst
  26. {
  27. WCHAR m_wszCookedInstName[256];
  28. WCHAR m_wszRawInstName[256];
  29. IWbemObjectAccess* m_pWMICookingInst;
  30. } CookingInstRec;
  31. struct tagCookingClass
  32. {
  33. WCHAR m_wszCookedClassName[256];
  34. WCHAR m_wszObservedCounter[256];
  35. long m_lHandle;
  36. CookingInstRec m_aCookingInst[10000];
  37. } g_aCookingData;
  38. */
  39. /* =
  40. {
  41. L"Win32_PerfCookedData_PerfProc_Process", 0, L"PercentProcessorTime", 0, { L"Win32_PerfCookedData_PerfProc_Process.Name=\"Idle\"", L"Win32_PerfRawData_PerfProc_Process.Name=\"Idle\""},
  42. L"Win32_PerfCookedData_PerfProc_Process", 0, L"PercentProcessorTime", 0, { L"Win32_PerfCookedData_PerfProc_Process.Name=\"System\"", L"Win32_PerfRawData_PerfProc_Process.Name=\"System\""},
  43. L"Win32_PerfCookedData_PerfProc_Process", 0, L"PercentProcessorTime", 0, { L"Win32_PerfCookedData_PerfProc_Process.Name=\"smss\"", L"Win32_PerfRawData_PerfProc_Process.Name=\"smss\""},
  44. L"Win32_PerfCookedData_PerfProc_Process", 0, L"PercentProcessorTime", 0, { L"Win32_PerfCookedData_PerfProc_Process.Name=\"csrss\"", L"Win32_PerfRawData_PerfProc_Process.Name=\"csrss\""},
  45. L"Win32_PerfCookedData_PerfProc_Process", 0, L"PercentProcessorTime", 0, { L"Win32_PerfCookedData_PerfProc_Process.Name=\"winlogon\"", L"Win32_PerfRawData_PerfProc_Process.Name=\"winlogon\""},
  46. L"Win32_PerfCookedData_PerfProc_Process", 0, L"PercentProcessorTime", 0, { L"Win32_PerfCookedData_PerfProc_Process.Name=\"services\"", L"Win32_PerfRawData_PerfProc_Process.Name=\"services\""},
  47. L"Win32_PerfCookedData_PerfProc_Process", 0, L"PercentProcessorTime", 0, { L"Win32_PerfCookedData_PerfProc_Process.Name=\"lsass\"", L"Win32_PerfRawData_PerfProc_Process.Name=\"lsass\""},
  48. L"Win32_PerfCookedData_PerfProc_Process", 0, L"PercentProcessorTime", 0, { L"Win32_PerfCookedData_PerfProc_Process.Name=\"svchost\"", L"Win32_PerfRawData_PerfProc_Process.Name=\"svchost\""},
  49. L"Win32_PerfCookedData_PerfProc_Process", 0, L"PercentProcessorTime", 0, { L"Win32_PerfCookedData_PerfProc_Process.Name=\"winmgmt\"", L"Win32_PerfRawData_PerfProc_Process.Name=\"winmgmt\""},
  50. L"Win32_PerfCookedData_PerfProc_Process", 0, L"PercentProcessorTime", 0, { L"Win32_PerfCookedData_PerfProc_Process.Name=\"explorer\"", L"Win32_PerfRawData_PerfProc_Process.Name=\"explorer\""},
  51. // L"Win32_PerfCookedData_PerfProc_Thread", 0, L"PercentProcessorTime" , 0 , { L"Win32_PerfCookedData_PerfProc_Thread.Name=\"Idle/0\"", L"Win32_PerfRawData_PerfProc_Thread.Name=\"Idle/0\""},
  52. // L"Win32_PerfCookedData_PerfProc_Thread", 0, L"PercentProcessorTime" , 0 , { L"Win32_PerfCookedData_PerfProc_Thread.Name=\"System/0\"", L"Win32_PerfRawData_PerfProc_Thread.Name=\"System/0\"" }
  53. };
  54. */
  55. HRESULT Init()
  56. {
  57. HRESULT hResult = S_OK;
  58. // Setup refresher
  59. // ===============
  60. hResult = CoCreateInstance( CLSID_WbemRefresher,
  61. NULL,
  62. CLSCTX_INPROC_SERVER,
  63. IID_IWbemRefresher,
  64. (void**) &g_pRefresher );
  65. if ( SUCCEEDED( hResult ) )
  66. {
  67. hResult = g_pRefresher->QueryInterface( IID_IWbemConfigureRefresher,
  68. (void**) &g_pConfig );
  69. }
  70. // Setup Cooking Class
  71. // ===================
  72. if ( SUCCEEDED( hResult ) )
  73. {
  74. BSTR strCookingObj = SysAllocString( WMI_COOKEDCLASS );
  75. hResult = g_pNameSpace->GetObject(strCookingObj, 0, NULL, &g_pCookedClass, NULL );
  76. SysFreeString( strCookingObj );
  77. if ( SUCCEEDED( hResult ) )
  78. {
  79. hResult = g_pCookedClass->QueryInterface( IID_IWbemObjectAccess, (void**)&g_pCookingAccess );
  80. if ( SUCCEEDED( hResult ) )
  81. {
  82. // CIMTYPE ct;
  83. // hResult = g_pCookingAccess->GetPropertyHandle( WMI_PROPERTY, &ct, &g_aCookingData.m_lHandle );
  84. }
  85. }
  86. }
  87. return hResult;
  88. }
  89. HRESULT CreateInstance( int nID, IWbemClassObject** ppCookingInst )
  90. {
  91. HRESULT hResult = S_OK;
  92. VARIANT vVar;
  93. vVar.vt = VT_I4;
  94. vVar.lVal = nID;
  95. hResult = g_pCookedClass->SpawnInstance( 0, ppCookingInst );
  96. if ( SUCCEEDED( hResult ) )
  97. {
  98. hResult = (*ppCookingInst)->Put( L"ID", 0, &vVar, CIM_UINT32 );
  99. }
  100. if ( SUCCEEDED( hResult ) )
  101. {
  102. hResult = g_pNameSpace->PutInstance( *ppCookingInst, WBEM_FLAG_CREATE_ONLY, NULL, NULL );
  103. }
  104. return hResult;
  105. }
  106. void TestRefreshCooker()
  107. {
  108. HRESULT hResult = WBEM_NO_ERROR;
  109. /* IWbemClassObject* pClassObj = NULL;
  110. IWbemClassObject* pRawClassInstance = NULL;
  111. IWbemObjectAccess* pCookingClass = NULL;
  112. IWbemObjectAccess* pCookingInstance = NULL;
  113. IWbemObjectAccess* pRawAccessInstance = NULL;
  114. IWbemObjectAccess* pRefInstance = NULL;
  115. IEnumWbemClassObject* pInstEnum = NULL;
  116. ULONG uReturned;
  117. long nNumCookedInst = 0;
  118. CRefreshableCooker RefreshableCooker;
  119. IEnumWbemClassObject *pEnum = NULL;
  120. // Enumerate all of the raw instances
  121. // ==================================
  122. BSTR strRawClass = SysAllocString( WMI_RAWCLASS );
  123. hResult = g_pNameSpace->CreateInstanceEnum( strRawClass, WBEM_FLAG_SHALLOW, NULL, &pInstEnum );
  124. SysFreeString( strRawClass );
  125. while ( WBEM_S_NO_ERROR == pInstEnum->Next(WBEM_INFINITE, 1, &pRawClassInstance, &uReturned ) )
  126. {
  127. int nID;
  128. IWbemClassObject* pCookedObject = NULL;
  129. VARIANT vVal;
  130. hResult = pRawClassInstance->Get( L"ID", 0, &vVal, NULL, NULL );
  131. nID = vVal.lVal;
  132. if ( SUCCEEDED( hResult ) )
  133. {
  134. WCHAR wszCookedObjName[256];
  135. swprintf( wszCookedObjName, L"%s.%s=%d", WMI_COOKEDCLASS, WMI_KEY_PROP, nID );
  136. BSTR strCookedObjName = SysAllocString(wszCookedObjName);
  137. hResult = g_pNameSpace->GetObject(strCookedObjName, 0, NULL, &pCookedObject, NULL );
  138. if ( FAILED(hResult) )
  139. {
  140. hResult = CreateInstance( nID, &pCookedObject );
  141. }
  142. SysFreeString(strCookedObjName);
  143. if ( SUCCEEDED( hResult ) )
  144. {
  145. // The raw instance
  146. // ================
  147. long lID;
  148. hResult = g_pConfig->AddObjectByTemplate( g_pNameSpace, pRawClassInstance, 0, NULL, &pClassObj, &lID );
  149. // Add the instance
  150. // ================
  151. hResult = pCookedObject->QueryInterface( IID_IWbemObjectAccess, (void**)&pCookingInstance);
  152. hResult = pClassObj->QueryInterface( IID_IWbemObjectAccess, (void**)&pRawAccessInstance );
  153. hResult = RefreshableCooker.AddInstance( g_pCookingAccess, pRawAccessInstance, &pCookingInstance, &lID );
  154. pRawAccessInstance->Release();
  155. pCookingInstance->Release();
  156. nNumCookedInst++;
  157. }
  158. }
  159. }
  160. printf("Setup complete. BeginRefreshing...\n");
  161. unsigned __int64 nVal = 0;
  162. long lHandle;
  163. CIMTYPE ct;
  164. pCookingInstance->GetPropertyHandle(L"Counter1", &ct, &lHandle);
  165. for (int nRefresh = 0; nRefresh < 1000; nRefresh++)
  166. {
  167. Sleep(1000);
  168. // g_pRefresher->Refresh( 0L );
  169. hResult = RefreshableCooker.Refresh();
  170. #ifndef WMI_NO_OUTPUT
  171. printf("%d: ", nRefresh);
  172. hResult = pCookingInstance->ReadQWORD( lHandle, &nVal );
  173. printf("\t%I64d", nVal);
  174. printf("\n");
  175. #endif //WMI_NO_OUTPUT
  176. }
  177. */
  178. }
  179. void Test()
  180. {
  181. HRESULT hResult = WBEM_NO_ERROR;
  182. IWbemClassObject* pObject = NULL;
  183. IWbemClassObject* pInstance = NULL;
  184. IWbemObjectAccess* pInstanceAccess = NULL;
  185. IWbemObjectAccess* pAccess = NULL;
  186. BSTR strObject = SysAllocString( L"Win32_Cooking_BasicHiPerf" );
  187. hResult = g_pNameSpace->GetObject( strObject, 0, NULL, &pObject, NULL );
  188. SysFreeString( strObject );
  189. pObject->QueryInterface( IID_IWbemObjectAccess, (void**)&pAccess );
  190. CWMISimpleObjectCooker ObjCooker;
  191. hResult = ObjCooker.SetClass( pAccess );
  192. if ( SUCCEEDED ( hResult ) )
  193. {
  194. pObject->SpawnInstance( 0, &pInstance );
  195. VARIANT vVar;
  196. vVar.vt = VT_I4;
  197. vVar.lVal = 1;
  198. pInstance->Put( L"ID", 0, &vVar, CIM_UINT32);
  199. long lID = 0;
  200. pInstance->QueryInterface( IID_IWbemObjectAccess, (void**)&pInstanceAccess );
  201. pInstance->Release();
  202. hResult = ObjCooker.SetCookedInstance( pInstanceAccess, &lID );
  203. if ( SUCCEEDED( hResult ) )
  204. {
  205. // Setup refresher
  206. // ===============
  207. IWbemRefresher* pRefresher = NULL;
  208. IWbemConfigureRefresher* pConfig = NULL;
  209. IWbemClassObject* pRefObj = NULL;
  210. IWbemObjectAccess* pRefObjAccess = NULL;
  211. long lID = 0;
  212. hResult = CoCreateInstance( CLSID_WbemRefresher,
  213. NULL,
  214. CLSCTX_INPROC_SERVER,
  215. IID_IWbemRefresher,
  216. (void**) &pRefresher );
  217. hResult = pRefresher->QueryInterface( IID_IWbemConfigureRefresher,
  218. (void**) &pConfig );
  219. WCHAR wcsObjName[256];
  220. swprintf( wcsObjName, L"Win32_BasicHiPerf.ID=0" );
  221. hResult = pConfig->AddObjectByPath( g_pNameSpace, wcsObjName, 0, NULL, &pRefObj, &lID );
  222. hResult = pRefObj->QueryInterface( IID_IWbemObjectAccess, (void**)&pRefObjAccess );
  223. hResult = pRefObj->Release();
  224. hResult = pRefresher->Refresh( 0L );
  225. hResult = ObjCooker.BeginCooking( lID, pRefObjAccess );
  226. hResult = pRefresher->Refresh( 0L );
  227. hResult = ObjCooker.Recalc();
  228. pRefresher->Release();
  229. pConfig->Release();
  230. pRefObjAccess->Release();
  231. }
  232. pInstanceAccess->Release();
  233. }
  234. pObject->Release();
  235. pAccess->Release();
  236. }
  237. HRESULT OpenNamespace( WCHAR* wszNamespace )
  238. {
  239. HRESULT hResult = WBEM_NO_ERROR;
  240. // Initialize COM
  241. // ==============
  242. hResult = CoInitializeEx( NULL, COINIT_MULTITHREADED );
  243. if ( FAILED( hResult ) )
  244. return hResult;
  245. // Setup default security parameters
  246. // =================================
  247. hResult = CoInitializeSecurity( NULL, -1, NULL, NULL,
  248. RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE,
  249. NULL, EOAC_NONE, NULL );
  250. if ( FAILED( hResult ) )
  251. return hResult;
  252. // Attach to WinMgmt
  253. // =================
  254. // Get the local locator object
  255. // ============================
  256. IWbemLocator* pWbemLocator = NULL;
  257. hResult = CoCreateInstance( CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (void**) &pWbemLocator );
  258. if (FAILED(hResult))
  259. return hResult;
  260. // Connect to the desired namespace
  261. // ================================
  262. BSTR bstrNameSpace;
  263. bstrNameSpace = SysAllocString( wszNamespace );
  264. hResult = pWbemLocator->ConnectServer( bstrNameSpace, // NameSpace Name
  265. NULL, // UserName
  266. NULL, // Password
  267. NULL, // Locale
  268. 0L, // Security Flags
  269. NULL, // Authority
  270. NULL, // Wbem Context
  271. &g_pNameSpace // Namespace
  272. );
  273. SysFreeString( bstrNameSpace );
  274. if ( FAILED( hResult ) )
  275. return hResult;
  276. // Before refreshing, we need to ensure that security is correctly set on the
  277. // namespace as the refresher will use those settings when it communicates with
  278. // WMI. This is especially important in remoting scenarios.
  279. IUnknown* pUnk = NULL;
  280. hResult = g_pNameSpace->QueryInterface( IID_IUnknown, (void**) &pUnk );
  281. if ( SUCCEEDED( hResult ) )
  282. {
  283. hResult = CoSetProxyBlanket( g_pNameSpace, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
  284. RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE,
  285. NULL, EOAC_NONE );
  286. if ( SUCCEEDED( hResult ) )
  287. {
  288. hResult = CoSetProxyBlanket( pUnk, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
  289. RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE,
  290. NULL, EOAC_NONE );
  291. }
  292. pUnk->Release();
  293. }
  294. if ( NULL != pWbemLocator )
  295. pWbemLocator->Release();
  296. return hResult;
  297. }
  298. int main(int argc, char* argv[])
  299. {
  300. HRESULT hResult = S_OK;
  301. hResult = OpenNamespace( WMI_NAMESPACE );
  302. if ( SUCCEEDED( hResult ) )
  303. {
  304. if ( SUCCEEDED( Init() ) )
  305. {
  306. // Test();
  307. TestRefreshCooker();
  308. }
  309. }
  310. // Cleanup
  311. // =======
  312. if ( NULL != g_pNameSpace )
  313. g_pNameSpace->Release();
  314. CoUninitialize();
  315. return 0;
  316. }