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.

316 lines
9.6 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. perfimag.c
  5. Abstract:
  6. This file implements an Performance Object that presents
  7. Image details performance object data
  8. Created:
  9. Bob Watson 22-Oct-1996
  10. Revision History
  11. --*/
  12. //
  13. // Include Files
  14. //
  15. #include <nt.h>
  16. #include <ntrtl.h>
  17. #include <nturtl.h>
  18. #include <windows.h>
  19. #include <winperf.h>
  20. #include <ntprfctr.h>
  21. #include <perfutil.h>
  22. #include "perfsprc.h"
  23. #include "perfmsg.h"
  24. #include "dataimag.h"
  25. DWORD APIENTRY
  26. BuildImageObject (
  27. IN OUT LPVOID *lppData,
  28. IN OUT LPDWORD lpcbTotalBytes,
  29. IN OUT LPDWORD lpNumObjectTypes,
  30. IN BOOL bLongImageName
  31. )
  32. /*++
  33. Routine Description:
  34. This routine will return the data for the processor object
  35. Arguments:
  36. IN OUT LPVOID *lppData
  37. IN: pointer to the address of the buffer to receive the completed
  38. PerfDataBlock and subordinate structures. This routine will
  39. append its data to the buffer starting at the point referenced
  40. by *lppData.
  41. OUT: points to the first byte after the data structure added by this
  42. routine. This routine updated the value at lppdata after appending
  43. its data.
  44. IN OUT LPDWORD lpcbTotalBytes
  45. IN: the address of the DWORD that tells the size in bytes of the
  46. buffer referenced by the lppData argument
  47. OUT: the number of bytes added by this routine is writted to the
  48. DWORD pointed to by this argument
  49. IN OUT LPDWORD NumObjectTypes
  50. IN: the address of the DWORD to receive the number of objects added
  51. by this routine
  52. OUT: the number of objects added by this routine is writted to the
  53. DWORD pointed to by this argument
  54. IN BOOL bLongImageName
  55. TRUE -- use the full path of the library file name in the instance
  56. FALSE - use only the file name in the instance
  57. Returns:
  58. 0 if successful, else Win 32 error code of failure
  59. --*/
  60. {
  61. DWORD TotalLen; // Length of the total return block
  62. PIMAGE_DATA_DEFINITION pImageDataDefinition;
  63. PPERF_INSTANCE_DEFINITION pPerfInstanceDefinition;
  64. PIMAGE_COUNTER_DATA pICD;
  65. DWORD dwNumInstances;
  66. DWORD dwImageNameLength;
  67. DWORD dwProcessIndex;
  68. PPROCESS_VA_INFO pThisProcess;
  69. PMODINFO pThisImage;
  70. dwNumInstances = 0;
  71. pImageDataDefinition = (IMAGE_DATA_DEFINITION *) *lppData;
  72. //
  73. // Check for sufficient space for Image object type definition
  74. //
  75. TotalLen = sizeof(IMAGE_DATA_DEFINITION) +
  76. sizeof(PERF_INSTANCE_DEFINITION) +
  77. MAX_PROCESS_NAME_LENGTH +
  78. sizeof(IMAGE_COUNTER_DATA);
  79. if ( *lpcbTotalBytes < TotalLen ) {
  80. *lpcbTotalBytes = (DWORD) 0;
  81. *lpNumObjectTypes = (DWORD) 0;
  82. return ERROR_MORE_DATA;
  83. }
  84. //
  85. // Define Page File data block
  86. //
  87. memcpy(pImageDataDefinition,
  88. &ImageDataDefinition,
  89. sizeof(IMAGE_DATA_DEFINITION));
  90. // update object title index if this is a Long Image object
  91. if (bLongImageName) {
  92. pImageDataDefinition->ImageObjectType.ObjectNameTitleIndex =
  93. LONG_IMAGE_OBJECT_TITLE_INDEX;
  94. pImageDataDefinition->ImageObjectType.ObjectHelpTitleIndex =
  95. LONG_IMAGE_OBJECT_TITLE_INDEX + 1;
  96. }
  97. pPerfInstanceDefinition = (PERF_INSTANCE_DEFINITION *)
  98. &pImageDataDefinition[1];
  99. // Now load data for each Image
  100. pThisProcess = pProcessVaInfo;
  101. dwProcessIndex = 0;
  102. TotalLen = sizeof(IMAGE_DATA_DEFINITION);
  103. while (pThisProcess) {
  104. pThisImage = pThisProcess->pMemBlockInfo;
  105. while (pThisImage) {
  106. dwImageNameLength = (bLongImageName ? pThisImage->LongInstanceName->Length :
  107. pThisImage->InstanceName->Length);
  108. dwImageNameLength += sizeof(WCHAR);
  109. dwImageNameLength = QWORD_MULTIPLE(dwImageNameLength);
  110. // see if this instance will fit
  111. TotalLen += sizeof (PERF_INSTANCE_DEFINITION) +
  112. dwImageNameLength +
  113. // (MAX_PROCESS_NAME_LENGTH + 1) * sizeof (WCHAR) +
  114. sizeof (DWORD) +
  115. sizeof (IMAGE_COUNTER_DATA);
  116. if ( *lpcbTotalBytes < TotalLen ) {
  117. *lpcbTotalBytes = (DWORD) 0;
  118. *lpNumObjectTypes = (DWORD) 0;
  119. return ERROR_MORE_DATA;
  120. }
  121. MonBuildInstanceDefinition (pPerfInstanceDefinition,
  122. (PVOID *) &pICD,
  123. EXPROCESS_OBJECT_TITLE_INDEX,
  124. dwProcessIndex,
  125. (DWORD)-1,
  126. (bLongImageName ? pThisImage->LongInstanceName->Buffer :
  127. pThisImage->InstanceName->Buffer));
  128. pICD->CounterBlock.ByteLength = sizeof(IMAGE_COUNTER_DATA);
  129. pICD->ImageAddrNoAccess = pThisImage->CommitVector[NOACCESS];
  130. pICD->ImageAddrReadOnly = pThisImage->CommitVector[READONLY];
  131. pICD->ImageAddrReadWrite = pThisImage->CommitVector[READWRITE];
  132. pICD->ImageAddrWriteCopy = pThisImage->CommitVector[WRITECOPY];
  133. pICD->ImageAddrExecute = pThisImage->CommitVector[EXECUTE];
  134. pICD->ImageAddrExecuteReadOnly = pThisImage->CommitVector[EXECUTEREAD];
  135. pICD->ImageAddrExecuteReadWrite = pThisImage->CommitVector[EXECUTEREADWRITE];
  136. pICD->ImageAddrExecuteWriteCopy = pThisImage->CommitVector[EXECUTEWRITECOPY];
  137. pPerfInstanceDefinition = (PERF_INSTANCE_DEFINITION *)&pICD[1];
  138. // adjust Total Length value to reflect ACTUAL size used
  139. TotalLen = (DWORD)((PCHAR) pPerfInstanceDefinition -
  140. (PCHAR) pImageDataDefinition);
  141. dwNumInstances++;
  142. pThisImage = pThisImage->pNextModule;
  143. }
  144. pThisProcess = pThisProcess->pNextProcess;
  145. dwProcessIndex++;
  146. }
  147. pImageDataDefinition->ImageObjectType.NumInstances += dwNumInstances;
  148. *lpcbTotalBytes =
  149. pImageDataDefinition->ImageObjectType.TotalByteLength =
  150. (DWORD)((PCHAR) pPerfInstanceDefinition -
  151. (PCHAR) pImageDataDefinition);
  152. #if DBG
  153. if (*lpcbTotalBytes > TotalLen ) {
  154. DbgPrint ("\nPERFPROC: Image Perf Ctr. Instance Size Underestimated:");
  155. DbgPrint ("\nPERFPROC: Estimated size: %d, Actual Size: %d", TotalLen, *lpcbTotalBytes);
  156. }
  157. #endif
  158. *lppData = (LPVOID) pPerfInstanceDefinition;
  159. // increment number of objects in this data block
  160. *lpNumObjectTypes = 1;
  161. return ERROR_SUCCESS;
  162. }
  163. DWORD APIENTRY
  164. CollectImageObjectData (
  165. IN OUT LPVOID *lppData,
  166. IN OUT LPDWORD lpcbTotalBytes,
  167. IN OUT LPDWORD lpNumObjectTypes
  168. )
  169. /*++
  170. Routine Description:
  171. This routine will return the data for the processor object
  172. Arguments:
  173. IN OUT LPVOID *lppData
  174. IN: pointer to the address of the buffer to receive the completed
  175. PerfDataBlock and subordinate structures. This routine will
  176. append its data to the buffer starting at the point referenced
  177. by *lppData.
  178. OUT: points to the first byte after the data structure added by this
  179. routine. This routine updated the value at lppdata after appending
  180. its data.
  181. IN OUT LPDWORD lpcbTotalBytes
  182. IN: the address of the DWORD that tells the size in bytes of the
  183. buffer referenced by the lppData argument
  184. OUT: the number of bytes added by this routine is writted to the
  185. DWORD pointed to by this argument
  186. IN OUT LPDWORD NumObjectTypes
  187. IN: the address of the DWORD to receive the number of objects added
  188. by this routine
  189. OUT: the number of objects added by this routine is writted to the
  190. DWORD pointed to by this argument
  191. Returns:
  192. 0 if successful, else Win 32 error code of failure
  193. --*/
  194. {
  195. return BuildImageObject (
  196. lppData,
  197. lpcbTotalBytes,
  198. lpNumObjectTypes,
  199. FALSE); // use short names
  200. }
  201. DWORD APIENTRY
  202. CollectLongImageObjectData (
  203. IN OUT LPVOID *lppData,
  204. IN OUT LPDWORD lpcbTotalBytes,
  205. IN OUT LPDWORD lpNumObjectTypes
  206. )
  207. /*++
  208. Routine Description:
  209. This routine will return the data for the processor object
  210. Arguments:
  211. IN OUT LPVOID *lppData
  212. IN: pointer to the address of the buffer to receive the completed
  213. PerfDataBlock and subordinate structures. This routine will
  214. append its data to the buffer starting at the point referenced
  215. by *lppData.
  216. OUT: points to the first byte after the data structure added by this
  217. routine. This routine updated the value at lppdata after appending
  218. its data.
  219. IN OUT LPDWORD lpcbTotalBytes
  220. IN: the address of the DWORD that tells the size in bytes of the
  221. buffer referenced by the lppData argument
  222. OUT: the number of bytes added by this routine is writted to the
  223. DWORD pointed to by this argument
  224. IN OUT LPDWORD NumObjectTypes
  225. IN: the address of the DWORD to receive the number of objects added
  226. by this routine
  227. OUT: the number of objects added by this routine is writted to the
  228. DWORD pointed to by this argument
  229. Returns:
  230. 0 if successful, else Win 32 error code of failure
  231. --*/
  232. {
  233. return BuildImageObject (
  234. lppData,
  235. lpcbTotalBytes,
  236. lpNumObjectTypes,
  237. TRUE); // use long names
  238. }