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.

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