Changeset 10868 in vbox for trunk/src/VBox/Main/win
- Timestamp:
- Jul 24, 2008 6:34:35 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 33686
- Location:
- trunk/src/VBox/Main/win
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/win/PerformanceWin.cpp
r10753 r10868 22 22 */ 23 23 24 #include <pdh.h> 25 #include <pdhmsg.h> 24 #include <Wbemidl.h> 26 25 #include <iprt/err.h> 27 26 27 #include "Logging.h" 28 28 #include "Performance.h" 29 30 //#pragma comment(lib, "pdh.lib")31 29 32 30 namespace pm { … … 44 42 virtual int getProcessMemoryUsage(RTPROCESS process, unsigned long *used); 45 43 44 virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle); 45 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total); 46 46 private: 47 int convertPdhStatusToRTErr(PDH_STATUS pdhStatus); 48 HCOUNTER addCounter(HQUERY hQuery, LPCTSTR name); 49 int getCounterValue(HCOUNTER hCounter, DWORD flags, unsigned long *value); 50 51 HQUERY mHostCpuLoadQuery; 52 HCOUNTER mHostCpuLoadUserCounter; 53 HCOUNTER mHostCpuLoadKernelCounter; 54 HCOUNTER mHostCpuLoadIdleCounter; 47 long getPropertyHandle(IWbemObjectAccess *objAccess, LPCWSTR name); 48 int getObjects(IWbemHiPerfEnum *mEnum, IWbemObjectAccess ***objArray, DWORD *numReturned); 49 50 IWbemRefresher *mRefresher; 51 IWbemServices *mNameSpace; 52 53 IWbemHiPerfEnum *mEnumProcessor; 54 long mEnumProcessorID; 55 long mHostCpuLoadNameHandle; 56 long mHostCpuLoadUserHandle; 57 long mHostCpuLoadKernelHandle; 58 long mHostCpuLoadIdleHandle; 59 60 IWbemHiPerfEnum *mEnumProcess; 61 long mEnumProcessID; 62 long mProcessPIDHandle; 63 long mProcessCpuLoadUserHandle; 64 long mProcessCpuLoadKernelHandle; 65 long mProcessCpuLoadTimestampHandle; 66 long mProcessMemoryUsedHandle; 55 67 }; 56 68 … … 61 73 } 62 74 63 CollectorWin::CollectorWin() : mHostCpuLoadQuery(0) 64 { 65 PDH_STATUS pdhStatus; 66 67 pdhStatus = PdhOpenQuery(NULL, NULL, &mHostCpuLoadQuery); 68 if (pdhStatus != ERROR_SUCCESS) 75 CollectorWin::CollectorWin() : mRefresher(0), mNameSpace(0), mEnumProcessor(0), mEnumProcess(0) 76 { 77 HRESULT hr = S_OK; 78 IWbemConfigureRefresher *pConfig = NULL; 79 IWbemLocator *pWbemLocator = NULL; 80 BSTR bstrNameSpace = NULL; 81 82 if (SUCCEEDED (hr = CoCreateInstance( 83 CLSID_WbemLocator, 84 NULL, 85 CLSCTX_INPROC_SERVER, 86 IID_IWbemLocator, 87 (void**) &pWbemLocator))) 88 { 89 // Connect to the desired namespace. 90 bstrNameSpace = SysAllocString(L"\\\\.\\root\\cimv2"); 91 if (bstrNameSpace) 92 { 93 hr = pWbemLocator->ConnectServer( 94 bstrNameSpace, 95 NULL, // User name 96 NULL, // Password 97 NULL, // Locale 98 0L, // Security flags 99 NULL, // Authority 100 NULL, // Wbem context 101 &mNameSpace); 102 } 103 pWbemLocator->Release(); 104 SysFreeString(bstrNameSpace); 105 } 106 107 if (FAILED (hr)) { 108 Log (("Failed to get namespace. HR = %x\n", hr)); 69 109 return; 70 71 mHostCpuLoadUserCounter = addCounter (mHostCpuLoadQuery, 72 L"\\Processor(_Total)\\% User Time"); 73 mHostCpuLoadKernelCounter = addCounter (mHostCpuLoadQuery, 74 L"\\Processor(_Total)\\% Privileged Time"); 75 mHostCpuLoadIdleCounter = addCounter (mHostCpuLoadQuery, 76 L"\\Processor(_Total)\\% Idle Time"); 110 } 111 112 if (SUCCEEDED (hr = CoCreateInstance( 113 CLSID_WbemRefresher, 114 NULL, 115 CLSCTX_INPROC_SERVER, 116 IID_IWbemRefresher, 117 (void**) &mRefresher))) 118 { 119 if (SUCCEEDED (hr = mRefresher->QueryInterface( 120 IID_IWbemConfigureRefresher, 121 (void **)&pConfig))) 122 { 123 // Add an enumerator to the refresher. 124 if (SUCCEEDED (hr = pConfig->AddEnum( 125 mNameSpace, 126 L"Win32_PerfRawData_PerfOS_Processor", 127 0, 128 NULL, 129 &mEnumProcessor, 130 &mEnumProcessorID))) 131 { 132 hr = pConfig->AddEnum( 133 mNameSpace, 134 L"Win32_PerfRawData_PerfProc_Process", 135 0, 136 NULL, 137 &mEnumProcess, 138 &mEnumProcessID); 139 } 140 pConfig->Release(); 141 } 142 } 143 144 145 if (FAILED (hr)) { 146 Log (("Failed to add enumerators. HR = %x\n", hr)); 147 return; 148 } 149 150 // Retrieve property handles 151 152 if (FAILED (hr = mRefresher->Refresh(0L))) 153 { 154 Log (("Refresher failed. HR = %x\n", hr)); 155 return; 156 } 157 158 IWbemObjectAccess **apEnumAccess = NULL; 159 DWORD dwNumReturned = 0; 160 161 if (RT_FAILURE(getObjects(mEnumProcessor, &apEnumAccess, &dwNumReturned))) 162 return; 163 164 mHostCpuLoadNameHandle = getPropertyHandle(apEnumAccess[0], L"Name"); 165 mHostCpuLoadUserHandle = getPropertyHandle(apEnumAccess[0], L"PercentUserTime"); 166 mHostCpuLoadKernelHandle = getPropertyHandle(apEnumAccess[0], L"PercentPrivilegedTime"); 167 mHostCpuLoadIdleHandle = getPropertyHandle(apEnumAccess[0], L"PercentProcessorTime"); 168 169 delete [] apEnumAccess; 170 171 if (RT_FAILURE(getObjects(mEnumProcess, &apEnumAccess, &dwNumReturned))) 172 return; 173 174 mProcessPIDHandle = getPropertyHandle(apEnumAccess[0], L"IDProcess"); 175 mProcessCpuLoadUserHandle = getPropertyHandle(apEnumAccess[0], L"PercentUserTime"); 176 mProcessCpuLoadKernelHandle = getPropertyHandle(apEnumAccess[0], L"PercentPrivilegedTime"); 177 mProcessCpuLoadTimestampHandle = getPropertyHandle(apEnumAccess[0], L"Timestamp_Sys100NS"); 178 mProcessMemoryUsedHandle = getPropertyHandle(apEnumAccess[0], L"WorkingSet"); 179 180 delete [] apEnumAccess; 77 181 } 78 182 79 183 CollectorWin::~CollectorWin() 80 184 { 81 if (mHostCpuLoadQuery) 82 PdhCloseQuery (mHostCpuLoadQuery); 83 } 84 85 int CollectorWin::convertPdhStatusToRTErr(PDH_STATUS pdhStatus) 86 { 87 switch (pdhStatus) 88 { 89 case PDH_INVALID_ARGUMENT: 90 return VERR_INVALID_PARAMETER; 91 case PDH_INVALID_HANDLE: 92 return VERR_INVALID_HANDLE; 93 } 94 95 return RTErrConvertFromWin32(pdhStatus); 96 } 97 98 HCOUNTER CollectorWin::addCounter(HQUERY hQuery, LPCTSTR name) 99 { 100 PDH_STATUS pdhStatus; 101 HCOUNTER hCounter; 102 103 pdhStatus = PdhAddCounter (hQuery, name, 0, &hCounter); 104 if (pdhStatus != ERROR_SUCCESS) 105 return 0; 106 return hCounter; 107 } 108 109 int CollectorWin::getCounterValue(HCOUNTER hCounter, DWORD flags, unsigned long *value) 110 { 111 PDH_STATUS pdhStatus; 112 PDH_FMT_COUNTERVALUE fmtValue; 113 114 pdhStatus = PdhGetFormattedCounterValue (hCounter, 115 PDH_FMT_LONG | flags, 116 NULL, 117 &fmtValue); 118 if (pdhStatus != ERROR_SUCCESS) 119 return convertPdhStatusToRTErr(pdhStatus); 120 121 *value = fmtValue.longValue; 122 185 if (NULL != mNameSpace) 186 { 187 mNameSpace->Release(); 188 } 189 if (NULL != mEnumProcessor) 190 { 191 mEnumProcessor->Release(); 192 } 193 if (NULL != mEnumProcess) 194 { 195 mEnumProcess->Release(); 196 } 197 if (NULL != mRefresher) 198 { 199 mRefresher->Release(); 200 } 201 } 202 203 long CollectorWin::getPropertyHandle(IWbemObjectAccess *objAccess, LPCWSTR name) 204 { 205 HRESULT hr; 206 CIMTYPE tmp; 207 long handle; 208 209 if (FAILED (hr = objAccess->GetPropertyHandle( 210 name, 211 &tmp, 212 &handle))) 213 { 214 Log (("Failed to get property handle for '%ls'. HR = %x\n", name, hr)); 215 return 0; /// @todo use throw 216 } 217 218 return handle; 219 } 220 221 int CollectorWin::getObjects(IWbemHiPerfEnum *mEnum, IWbemObjectAccess ***objArray, DWORD *numReturned) 222 { 223 HRESULT hr; 224 DWORD dwNumObjects = 0; 225 226 *objArray = NULL; 227 *numReturned = 0; 228 hr = mEnum->GetObjects(0L, dwNumObjects, *objArray, numReturned); 229 230 // If the buffer was not big enough, 231 // allocate a bigger buffer and retry. 232 if (hr == WBEM_E_BUFFER_TOO_SMALL 233 && *numReturned > dwNumObjects) 234 { 235 *objArray = new IWbemObjectAccess*[*numReturned]; 236 if (NULL == *objArray) 237 { 238 Log (("Could not allocate enumerator access objects\n")); 239 return VERR_NO_MEMORY; 240 } 241 242 SecureZeroMemory(*objArray, 243 *numReturned*sizeof(IWbemObjectAccess*)); 244 dwNumObjects = *numReturned; 245 246 if (FAILED (hr = mEnum->GetObjects(0L, 247 dwNumObjects, *objArray, numReturned))) 248 { 249 delete [] objArray; 250 Log (("Failed to get objects from enumerator. HR = %x\n", hr)); 251 return VERR_INTERNAL_ERROR; 252 } 253 } 254 else if (FAILED (hr)) 255 { 256 Log (("Failed to get objects from enumerator. HR = %x\n", hr)); 257 return VERR_INTERNAL_ERROR; 258 } 259 123 260 return VINF_SUCCESS; 124 261 } … … 126 263 int CollectorWin::getHostCpuLoad(unsigned long *user, unsigned long *kernel, unsigned long *idle) 127 264 { 128 int rc; 129 PDH_STATUS pdhStatus; 130 131 pdhStatus = PdhCollectQueryData (mHostCpuLoadQuery); 132 if (pdhStatus != ERROR_SUCCESS) 133 return convertPdhStatusToRTErr(pdhStatus); 134 135 rc = getCounterValue (mHostCpuLoadUserCounter, PDH_FMT_1000, user); 136 AssertRCReturn(rc, rc); 137 138 rc = getCounterValue (mHostCpuLoadKernelCounter, PDH_FMT_1000, kernel); 139 AssertRCReturn(rc, rc); 140 141 rc = getCounterValue (mHostCpuLoadIdleCounter, PDH_FMT_1000, idle); 142 AssertRCReturn(rc, rc); 143 144 return VINF_SUCCESS; 265 return VERR_NOT_IMPLEMENTED; 266 } 267 268 int CollectorWin::getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle) 269 { 270 HRESULT hr; 271 IWbemObjectAccess **apEnumAccess = NULL; 272 DWORD dwNumReturned = 0; 273 274 LogFlowThisFuncEnter(); 275 276 if (FAILED (hr = mRefresher->Refresh(0L))) 277 { 278 Log (("Refresher failed. HR = %x\n", hr)); 279 return VERR_INTERNAL_ERROR; 280 } 281 282 int rc = getObjects(mEnumProcessor, &apEnumAccess, &dwNumReturned); 283 if (RT_FAILURE(rc)) 284 return rc; 285 286 for (unsigned i = 0; i < dwNumReturned; i++) 287 { 288 long bytesRead = 0; 289 WCHAR tmpBuf[200]; 290 291 if (FAILED (hr = apEnumAccess[i]->ReadPropertyValue( 292 mHostCpuLoadNameHandle, 293 sizeof(tmpBuf), 294 &bytesRead, 295 (byte*)tmpBuf))) 296 { 297 Log (("Failed to read 'Name' property. HR = %x\n", hr)); 298 return VERR_INTERNAL_ERROR; 299 } 300 if (wcscmp(tmpBuf, L"_Total") == 0) 301 { 302 if (FAILED (hr = apEnumAccess[i]->ReadQWORD( 303 mHostCpuLoadUserHandle, 304 user))) 305 { 306 Log (("Failed to read 'PercentUserTime' property. HR = %x\n", hr)); 307 return VERR_INTERNAL_ERROR; 308 } 309 if (FAILED (hr = apEnumAccess[i]->ReadQWORD( 310 mHostCpuLoadKernelHandle, 311 kernel))) 312 { 313 Log (("Failed to read 'PercentPrivilegedTime' property. HR = %x\n", hr)); 314 return VERR_INTERNAL_ERROR; 315 } 316 if (FAILED (hr = apEnumAccess[i]->ReadQWORD( 317 mHostCpuLoadIdleHandle, 318 idle))) 319 { 320 Log (("Failed to read 'PercentProcessorTime' property. HR = %x\n", hr)); 321 return VERR_INTERNAL_ERROR; 322 } 323 rc = VINF_SUCCESS; 324 } 325 apEnumAccess[i]->Release(); 326 apEnumAccess[i] = NULL; 327 } 328 delete [] apEnumAccess; 329 330 LogFlowThisFunc(("user=%lu kernel=%lu idle=%lu\n", *user, *kernel, *idle)); 331 LogFlowThisFuncLeave(); 332 333 return rc; 145 334 } 146 335 147 336 int CollectorWin::getHostCpuMHz(unsigned long *mhz) 148 337 { 149 return E_NOTIMPL;338 return VERR_NOT_IMPLEMENTED; 150 339 } 151 340 … … 169 358 int CollectorWin::getProcessCpuLoad(RTPROCESS process, unsigned long *user, unsigned long *kernel) 170 359 { 171 return E_NOTIMPL; 360 return VERR_NOT_IMPLEMENTED; 361 } 362 363 int CollectorWin::getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total) 364 { 365 HRESULT hr; 366 IWbemObjectAccess **apEnumAccess = NULL; 367 DWORD dwNumReturned = 0; 368 369 LogFlowThisFuncEnter(); 370 371 if (FAILED (hr = mRefresher->Refresh(0L))) 372 { 373 Log (("Refresher failed. HR = %x\n", hr)); 374 return VERR_INTERNAL_ERROR; 375 } 376 377 int rc = getObjects(mEnumProcess, &apEnumAccess, &dwNumReturned); 378 if (RT_FAILURE(rc)) 379 return rc; 380 381 rc = VERR_NOT_FOUND; 382 383 for (unsigned i = 0; i < dwNumReturned; i++) 384 { 385 DWORD dwIDProcess; 386 387 if (FAILED (hr = apEnumAccess[i]->ReadDWORD( 388 mProcessPIDHandle, 389 &dwIDProcess))) 390 { 391 Log (("Failed to read 'IDProcess' property. HR = %x\n", hr)); 392 return VERR_INTERNAL_ERROR; 393 } 394 LogFlowThisFunc (("Matching machine process %x against %x...\n", process, dwIDProcess)); 395 if (dwIDProcess == process) 396 { 397 LogFlowThisFunc (("Match found.\n")); 398 if (FAILED (hr = apEnumAccess[i]->ReadQWORD( 399 mProcessCpuLoadUserHandle, 400 user))) 401 { 402 Log (("Failed to read 'PercentUserTime' property. HR = %x\n", hr)); 403 return VERR_INTERNAL_ERROR; 404 } 405 if (FAILED (hr = apEnumAccess[i]->ReadQWORD( 406 mProcessCpuLoadKernelHandle, 407 kernel))) 408 { 409 Log (("Failed to read 'PercentPrivilegedTime' property. HR = %x\n", hr)); 410 return VERR_INTERNAL_ERROR; 411 } 412 if (FAILED (hr = apEnumAccess[i]->ReadQWORD( 413 mProcessCpuLoadTimestampHandle, 414 total))) 415 { 416 Log (("Failed to read 'Timestamp_Sys100NS' property. HR = %x\n", hr)); 417 return VERR_INTERNAL_ERROR; 418 } 419 rc = VINF_SUCCESS; 420 } 421 apEnumAccess[i]->Release(); 422 apEnumAccess[i] = NULL; 423 } 424 delete [] apEnumAccess; 425 426 LogFlowThisFunc(("user=%lu kernel=%lu total=%lu\n", *user, *kernel, *total)); 427 LogFlowThisFuncLeave(); 428 429 return rc; 172 430 } 173 431 174 432 int CollectorWin::getProcessMemoryUsage(RTPROCESS process, unsigned long *used) 175 433 { 176 return E_NOTIMPL; 177 } 178 179 } 434 HRESULT hr; 435 IWbemObjectAccess **apEnumAccess = NULL; 436 DWORD dwNumReturned = 0; 437 438 LogFlowThisFuncEnter(); 439 440 if (FAILED (hr = mRefresher->Refresh(0L))) 441 { 442 Log (("Refresher failed. HR = %x\n", hr)); 443 return VERR_INTERNAL_ERROR; 444 } 445 446 int rc = getObjects(mEnumProcess, &apEnumAccess, &dwNumReturned); 447 if (RT_FAILURE(rc)) 448 return rc; 449 450 rc = VERR_NOT_FOUND; 451 452 for (unsigned i = 0; i < dwNumReturned; i++) 453 { 454 DWORD dwIDProcess; 455 456 if (FAILED (hr = apEnumAccess[i]->ReadDWORD( 457 mProcessPIDHandle, 458 &dwIDProcess))) 459 { 460 Log (("Failed to read 'IDProcess' property. HR = %x\n", hr)); 461 return VERR_INTERNAL_ERROR; 462 } 463 if (dwIDProcess == process) 464 { 465 uint64_t u64used = 0; 466 467 if (FAILED (hr = apEnumAccess[i]->ReadQWORD( 468 mProcessMemoryUsedHandle, 469 &u64used))) 470 { 471 Log (("Failed to read 'WorkingSet' property. HR = %x\n", hr)); 472 return VERR_INTERNAL_ERROR; 473 } 474 *used = (unsigned long)(u64used / 1024); 475 rc = VINF_SUCCESS; 476 } 477 apEnumAccess[i]->Release(); 478 apEnumAccess[i] = NULL; 479 } 480 delete [] apEnumAccess; 481 482 LogFlowThisFunc(("used=%lu\n", *used)); 483 LogFlowThisFuncLeave(); 484 485 return rc; 486 } 487 488 } -
trunk/src/VBox/Main/win/svcmain.cpp
r8155 r10868 173 173 #endif 174 174 _ASSERTE(SUCCEEDED(hRes)); 175 /* 176 * Need to initialize security to access performance enumerators. 177 */ 178 hRes = CoInitializeSecurity( 179 NULL, 180 -1, 181 NULL, 182 NULL, 183 RPC_C_AUTHN_LEVEL_NONE, 184 RPC_C_IMP_LEVEL_IMPERSONATE, 185 NULL, EOAC_NONE, 0); 186 _ASSERTE(SUCCEEDED(hRes)); 175 187 _Module.Init(ObjectMap, hInstance, &LIBID_VirtualBox); 176 188 _Module.dwThreadID = GetCurrentThreadId();
Note:
See TracChangeset
for help on using the changeset viewer.