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.

601 lines
14 KiB

  1. #include <windows.h>
  2. #include <winperf.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <tchar.h>
  7. #include "perfdata.h"
  8. const LPWSTR NamesKey = (const LPWSTR)L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib";
  9. const LPWSTR DefaultLangId = (const LPWSTR)L"009";
  10. const LPWSTR Counters = (const LPWSTR)L"Counters";
  11. const LPWSTR Help = (const LPWSTR)L"Help";
  12. const LPWSTR LastHelp = (const LPWSTR)L"Last Help";
  13. const LPWSTR LastCounter = (const LPWSTR)L"Last Counter";
  14. const LPWSTR Slash = (const LPWSTR)L"\\";
  15. // the following strings are for getting texts from perflib
  16. #define OLD_VERSION 0x010000
  17. const LPWSTR VersionName = (const LPWSTR)L"Version";
  18. const LPWSTR CounterName = (const LPWSTR)L"Counter ";
  19. const LPWSTR HelpName = (const LPWSTR)L"Explain ";
  20. LPMEMORY
  21. MemoryAllocate (
  22. DWORD dwSize
  23. )
  24. { // MemoryAllocate
  25. HMEMORY hMemory ;
  26. LPMEMORY lpMemory ;
  27. hMemory = GlobalAlloc (GHND, dwSize);
  28. if (!hMemory)
  29. return (NULL);
  30. lpMemory = GlobalLock (hMemory);
  31. if (!lpMemory)
  32. GlobalFree (hMemory);
  33. return (lpMemory);
  34. } // MemoryAllocate
  35. VOID
  36. MemoryFree (
  37. LPMEMORY lpMemory
  38. )
  39. { // MemoryFree
  40. HMEMORY hMemory ;
  41. if (!lpMemory)
  42. return ;
  43. hMemory = GlobalHandle (lpMemory);
  44. if (hMemory)
  45. { // if
  46. GlobalUnlock (hMemory);
  47. GlobalFree (hMemory);
  48. } // if
  49. } // MemoryFree
  50. DWORD
  51. MemorySize (
  52. LPMEMORY lpMemory
  53. )
  54. {
  55. HMEMORY hMemory ;
  56. hMemory = GlobalHandle (lpMemory);
  57. if (!hMemory)
  58. return (0L);
  59. return (DWORD)(GlobalSize (hMemory));
  60. }
  61. LPMEMORY
  62. MemoryResize (
  63. LPMEMORY lpMemory,
  64. DWORD dwNewSize
  65. )
  66. {
  67. HMEMORY hMemory ;
  68. LPMEMORY lpNewMemory ;
  69. hMemory = GlobalHandle (lpMemory);
  70. if (!hMemory)
  71. return (NULL);
  72. GlobalUnlock (hMemory);
  73. hMemory = GlobalReAlloc (hMemory, dwNewSize, GHND);
  74. if (!hMemory)
  75. return (NULL);
  76. lpNewMemory = GlobalLock (hMemory);
  77. return (lpNewMemory);
  78. } // MemoryResize
  79. LPWSTR
  80. *BuildNameTable(
  81. LPWSTR szComputerName, // computer to query names from
  82. LPWSTR lpszLangId, // unicode value of Language subkey
  83. PDWORD pdwLastItem // size of array in elements
  84. )
  85. /*++
  86. BuildNameTable
  87. Arguments:
  88. hKeyRegistry
  89. Handle to an open registry (this can be local or remote.) and
  90. is the value returned by RegConnectRegistry or a default key.
  91. lpszLangId
  92. The unicode id of the language to look up. (default is 409)
  93. Return Value:
  94. pointer to an allocated table. (the caller must free it when finished!)
  95. the table is an array of pointers to zero terminated strings. NULL is
  96. returned if an error occured.
  97. --*/
  98. {
  99. LPWSTR *lpReturnValue;
  100. LPWSTR *lpCounterId;
  101. LPWSTR lpCounterNames;
  102. LPWSTR lpHelpText;
  103. LPWSTR lpThisName;
  104. LONG lWin32Status;
  105. DWORD dwLastError;
  106. DWORD dwValueType;
  107. DWORD dwArraySize;
  108. DWORD dwBufferSize;
  109. DWORD dwCounterSize;
  110. DWORD dwHelpSize;
  111. DWORD dwThisCounter;
  112. DWORD dwSystemVersion;
  113. DWORD dwLastId;
  114. DWORD dwLastHelpId;
  115. HKEY hKeyRegistry = NULL;
  116. HKEY hKeyValue = NULL;
  117. HKEY hKeyNames = NULL;
  118. LPWSTR lpValueNameString;
  119. WCHAR CounterNameBuffer [50];
  120. WCHAR HelpNameBuffer [50];
  121. lpValueNameString = NULL; //initialize to NULL
  122. lpReturnValue = NULL;
  123. if (szComputerName == NULL) {
  124. // use local machine
  125. hKeyRegistry = HKEY_LOCAL_MACHINE;
  126. } else {
  127. if (RegConnectRegistry (szComputerName,
  128. HKEY_LOCAL_MACHINE, &hKeyRegistry) != ERROR_SUCCESS) {
  129. // unable to connect to registry
  130. return NULL;
  131. }
  132. }
  133. // check for null arguments and insert defaults if necessary
  134. if (!lpszLangId) {
  135. lpszLangId = DefaultLangId;
  136. }
  137. // open registry to get number of items for computing array size
  138. lWin32Status = RegOpenKeyEx (
  139. hKeyRegistry,
  140. NamesKey,
  141. RESERVED,
  142. KEY_READ,
  143. &hKeyValue);
  144. if (lWin32Status != ERROR_SUCCESS) {
  145. goto BNT_BAILOUT;
  146. }
  147. // get number of items
  148. dwBufferSize = sizeof (dwLastHelpId);
  149. lWin32Status = RegQueryValueEx (
  150. hKeyValue,
  151. LastHelp,
  152. RESERVED,
  153. &dwValueType,
  154. (LPBYTE)&dwLastHelpId,
  155. &dwBufferSize);
  156. if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {
  157. goto BNT_BAILOUT;
  158. }
  159. // get number of items
  160. dwBufferSize = sizeof (dwLastId);
  161. lWin32Status = RegQueryValueEx (
  162. hKeyValue,
  163. LastCounter,
  164. RESERVED,
  165. &dwValueType,
  166. (LPBYTE)&dwLastId,
  167. &dwBufferSize);
  168. if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {
  169. goto BNT_BAILOUT;
  170. }
  171. if (dwLastId < dwLastHelpId)
  172. dwLastId = dwLastHelpId;
  173. dwArraySize = dwLastId * sizeof(LPWSTR);
  174. // get Perflib system version
  175. dwBufferSize = sizeof (dwSystemVersion);
  176. lWin32Status = RegQueryValueEx (
  177. hKeyValue,
  178. VersionName,
  179. RESERVED,
  180. &dwValueType,
  181. (LPBYTE)&dwSystemVersion,
  182. &dwBufferSize);
  183. if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {
  184. dwSystemVersion = OLD_VERSION;
  185. }
  186. if (dwSystemVersion == OLD_VERSION) {
  187. // get names from registry
  188. lpValueNameString = MemoryAllocate (
  189. lstrlen(NamesKey) * sizeof (WCHAR) +
  190. lstrlen(Slash) * sizeof (WCHAR) +
  191. lstrlen(lpszLangId) * sizeof (WCHAR) +
  192. sizeof (UNICODE_NULL));
  193. if (!lpValueNameString) goto BNT_BAILOUT;
  194. lstrcpy (lpValueNameString, NamesKey);
  195. lstrcat (lpValueNameString, Slash);
  196. lstrcat (lpValueNameString, lpszLangId);
  197. lWin32Status = RegOpenKeyEx (
  198. hKeyRegistry,
  199. lpValueNameString,
  200. RESERVED,
  201. KEY_READ,
  202. &hKeyNames);
  203. } else {
  204. if (szComputerName == NULL) {
  205. hKeyNames = HKEY_PERFORMANCE_DATA;
  206. } else {
  207. if (RegConnectRegistry (szComputerName,
  208. HKEY_PERFORMANCE_DATA, &hKeyNames) != ERROR_SUCCESS) {
  209. goto BNT_BAILOUT;
  210. }
  211. }
  212. lstrcpy (CounterNameBuffer, CounterName);
  213. lstrcat (CounterNameBuffer, lpszLangId);
  214. lstrcpy (HelpNameBuffer, HelpName);
  215. lstrcat (HelpNameBuffer, lpszLangId);
  216. }
  217. // get size of counter names and add that to the arrays
  218. if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;
  219. dwBufferSize = 0;
  220. lWin32Status = RegQueryValueEx (
  221. hKeyNames,
  222. dwSystemVersion == OLD_VERSION ? Counters : CounterNameBuffer,
  223. RESERVED,
  224. &dwValueType,
  225. NULL,
  226. &dwBufferSize);
  227. if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;
  228. dwCounterSize = dwBufferSize;
  229. // get size of counter names and add that to the arrays
  230. if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;
  231. dwBufferSize = 0;
  232. lWin32Status = RegQueryValueEx (
  233. hKeyNames,
  234. dwSystemVersion == OLD_VERSION ? Help : HelpNameBuffer,
  235. RESERVED,
  236. &dwValueType,
  237. NULL,
  238. &dwBufferSize);
  239. if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;
  240. dwHelpSize = dwBufferSize;
  241. lpReturnValue = MemoryAllocate (dwArraySize + dwCounterSize + dwHelpSize);
  242. if (!lpReturnValue) goto BNT_BAILOUT;
  243. // initialize pointers into buffer
  244. lpCounterId = lpReturnValue;
  245. lpCounterNames = (LPWSTR)((LPBYTE)lpCounterId + dwArraySize);
  246. lpHelpText = (LPWSTR)((LPBYTE)lpCounterNames + dwCounterSize);
  247. // read counters into memory
  248. dwBufferSize = dwCounterSize;
  249. lWin32Status = RegQueryValueEx (
  250. hKeyNames,
  251. dwSystemVersion == OLD_VERSION ? Counters : CounterNameBuffer,
  252. RESERVED,
  253. &dwValueType,
  254. (LPVOID)lpCounterNames,
  255. &dwBufferSize);
  256. if (!lpReturnValue) goto BNT_BAILOUT;
  257. dwBufferSize = dwHelpSize;
  258. lWin32Status = RegQueryValueEx (
  259. hKeyNames,
  260. dwSystemVersion == OLD_VERSION ? Help : HelpNameBuffer,
  261. RESERVED,
  262. &dwValueType,
  263. (LPVOID)lpHelpText,
  264. &dwBufferSize);
  265. if (!lpReturnValue) goto BNT_BAILOUT;
  266. // load counter array items
  267. for (lpThisName = lpCounterNames;
  268. *lpThisName;
  269. lpThisName += (lstrlen(lpThisName)+1) ) {
  270. // first string should be an integer (in decimal unicode digits)
  271. dwThisCounter = wcstoul (lpThisName, NULL, 10);
  272. // point to corresponding counter name
  273. lpThisName += (lstrlen(lpThisName)+1);
  274. // and load array element;
  275. lpCounterId[dwThisCounter] = lpThisName;
  276. }
  277. for (lpThisName = lpHelpText;
  278. *lpThisName;
  279. lpThisName += (lstrlen(lpThisName)+1) ) {
  280. // first string should be an integer (in decimal unicode digits)
  281. dwThisCounter = wcstoul (lpThisName, NULL, 10);
  282. // point to corresponding counter name
  283. lpThisName += (lstrlen(lpThisName)+1);
  284. // and load array element;
  285. lpCounterId[dwThisCounter] = lpThisName;
  286. }
  287. if (pdwLastItem) *pdwLastItem = dwLastId;
  288. MemoryFree ((LPVOID)lpValueNameString);
  289. RegCloseKey (hKeyValue);
  290. if (dwSystemVersion == OLD_VERSION)
  291. RegCloseKey (hKeyNames);
  292. return lpReturnValue;
  293. BNT_BAILOUT:
  294. if (lWin32Status != ERROR_SUCCESS) {
  295. dwLastError = GetLastError();
  296. }
  297. if (lpValueNameString) {
  298. MemoryFree ((LPVOID)lpValueNameString);
  299. }
  300. if (lpReturnValue) {
  301. MemoryFree ((LPVOID)lpReturnValue);
  302. }
  303. if (hKeyValue) RegCloseKey (hKeyValue);
  304. if (hKeyNames) RegCloseKey (hKeyNames);
  305. if (hKeyRegistry) RegCloseKey (hKeyNames);
  306. return NULL;
  307. }
  308. PPERF_OBJECT_TYPE
  309. FirstObject (
  310. IN PPERF_DATA_BLOCK pPerfData
  311. )
  312. {
  313. return ((PPERF_OBJECT_TYPE) ((PBYTE) pPerfData + pPerfData->HeaderLength));
  314. }
  315. PPERF_OBJECT_TYPE
  316. NextObject (
  317. IN PPERF_OBJECT_TYPE pObject
  318. )
  319. { // NextObject
  320. DWORD dwOffset;
  321. dwOffset = pObject->TotalByteLength;
  322. if (dwOffset != 0) {
  323. return ((PPERF_OBJECT_TYPE) ((PBYTE) pObject + dwOffset));
  324. } else {
  325. return NULL;
  326. }
  327. } // NextObject
  328. PERF_OBJECT_TYPE *
  329. GetObjectDefByTitleIndex(
  330. IN PERF_DATA_BLOCK *pDataBlock,
  331. IN DWORD ObjectTypeTitleIndex
  332. )
  333. {
  334. DWORD NumTypeDef;
  335. PERF_OBJECT_TYPE *pObjectDef;
  336. pObjectDef = FirstObject(pDataBlock);
  337. for ( NumTypeDef = 0;
  338. NumTypeDef < pDataBlock->NumObjectTypes;
  339. NumTypeDef++ ) {
  340. if ( pObjectDef->ObjectNameTitleIndex == ObjectTypeTitleIndex ) {
  341. return pObjectDef;
  342. }
  343. pObjectDef = NextObject(pObjectDef);
  344. }
  345. return 0;
  346. }
  347. PERF_INSTANCE_DEFINITION *
  348. FirstInstance(
  349. IN PERF_OBJECT_TYPE *pObjectDef
  350. )
  351. {
  352. return (PERF_INSTANCE_DEFINITION *)
  353. ((PCHAR) pObjectDef + pObjectDef->DefinitionLength);
  354. }
  355. PERF_INSTANCE_DEFINITION *
  356. NextInstance(
  357. IN PERF_INSTANCE_DEFINITION *pInstDef
  358. )
  359. {
  360. PERF_COUNTER_BLOCK *pCounterBlock;
  361. pCounterBlock = (PERF_COUNTER_BLOCK *)
  362. ((PCHAR) pInstDef + pInstDef->ByteLength);
  363. return (PERF_INSTANCE_DEFINITION *)
  364. ((PCHAR) pCounterBlock + pCounterBlock->ByteLength);
  365. }
  366. PERF_INSTANCE_DEFINITION *
  367. GetInstance(
  368. IN PERF_OBJECT_TYPE *pObjectDef,
  369. IN LONG InstanceNumber
  370. )
  371. {
  372. PERF_INSTANCE_DEFINITION *pInstanceDef;
  373. LONG NumInstance;
  374. if (!pObjectDef)
  375. {
  376. return 0;
  377. }
  378. pInstanceDef = FirstInstance(pObjectDef);
  379. for ( NumInstance = 0;
  380. NumInstance < pObjectDef->NumInstances;
  381. NumInstance++ )
  382. {
  383. if ( InstanceNumber == NumInstance )
  384. {
  385. return pInstanceDef;
  386. }
  387. pInstanceDef = NextInstance(pInstanceDef);
  388. }
  389. return 0;
  390. }
  391. PERF_COUNTER_DEFINITION *
  392. FirstCounter(
  393. PERF_OBJECT_TYPE *pObjectDef
  394. )
  395. {
  396. return (PERF_COUNTER_DEFINITION *)
  397. ((PCHAR) pObjectDef + pObjectDef->HeaderLength);
  398. }
  399. PERF_COUNTER_DEFINITION *
  400. NextCounter(
  401. PERF_COUNTER_DEFINITION *pCounterDef
  402. )
  403. {
  404. DWORD dwOffset;
  405. dwOffset = pCounterDef->ByteLength;
  406. if (dwOffset != 0) {
  407. return (PERF_COUNTER_DEFINITION *)
  408. ((PCHAR) pCounterDef + dwOffset);
  409. } else {
  410. return NULL;
  411. }
  412. }
  413. #pragma warning ( disable : 4127 )
  414. LONG
  415. GetSystemPerfData (
  416. IN HKEY hKeySystem,
  417. IN PPERF_DATA_BLOCK *pPerfData,
  418. IN DWORD dwIndex // 0 = Global, 1 = Costly
  419. )
  420. { // GetSystemPerfData
  421. LONG lError ;
  422. DWORD Size;
  423. DWORD Type;
  424. printf ("\nGetSystemPerfdata entered in line %d of %s", __LINE__, __FILE__);
  425. if (dwIndex >= 2) {
  426. return !ERROR_SUCCESS;
  427. }
  428. if (*pPerfData == NULL) {
  429. *pPerfData = MemoryAllocate (INITIAL_SIZE);
  430. if (*pPerfData == NULL) {
  431. printf ("\nMemory Allocation Failure in line %d of %s", __LINE__, __FILE__);
  432. return ERROR_OUTOFMEMORY;
  433. }
  434. }
  435. while (TRUE) {
  436. Size = MemorySize (*pPerfData);
  437. lError = RegQueryValueEx (
  438. hKeySystem,
  439. dwIndex == 0 ?
  440. (LPCWSTR)L"Global" :
  441. (LPCWSTR)L"Costly",
  442. RESERVED,
  443. &Type,
  444. (LPBYTE)*pPerfData,
  445. &Size);
  446. if ((!lError) &&
  447. (Size > 0) &&
  448. ((*pPerfData)->Signature[0] == (WCHAR)'P') &&
  449. ((*pPerfData)->Signature[1] == (WCHAR)'E') &&
  450. ((*pPerfData)->Signature[2] == (WCHAR)'R') &&
  451. ((*pPerfData)->Signature[3] == (WCHAR)'F')) {
  452. return (ERROR_SUCCESS);
  453. }
  454. if (lError == ERROR_MORE_DATA) {
  455. *pPerfData = MemoryResize (
  456. *pPerfData,
  457. MemorySize (*pPerfData) +
  458. EXTEND_SIZE);
  459. if (*pPerfData == NULL) {
  460. return (lError);
  461. }
  462. } else {
  463. return (lError);
  464. }
  465. }
  466. } // GetSystemPerfData
  467. #pragma warning ( default : 4127 )