Leaked source code of windows server 2003

291 lines
8.9 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. grovperf.cpp
  5. Abstract:
  6. SIS Groveler performance DLL main file
  7. Authors:
  8. John Douceur, 1998
  9. Environment:
  10. User Mode
  11. Revision History:
  12. --*/
  13. #include "all.hxx"
  14. static _TCHAR service_name[] = L"Groveler";
  15. static DWORD first_counter;
  16. static DWORD first_help;
  17. static int open_count = 0;
  18. static SharedData *shared_data = NULL;
  19. static const int ms_per_100ns_inv = 10000;
  20. static __int64 total_counter[num_perf_counters];
  21. extern "C" DWORD CALLBACK OpenGrovelerPerformanceData(LPWSTR lpDeviceNames)
  22. {
  23. if (open_count == 0)
  24. {
  25. shared_data = new SharedData;
  26. ASSERT(shared_data != NULL);
  27. HKEY path_key;
  28. _TCHAR perf_path[1024];
  29. (void)StringCbPrintf(perf_path,
  30. sizeof(perf_path),
  31. _T("SYSTEM\\CurrentControlSet\\Services\\%s\\Performance"),
  32. service_name);
  33. long result =
  34. RegOpenKeyEx(HKEY_LOCAL_MACHINE, perf_path, 0, KEY_READ, &path_key);
  35. ASSERT_PRINTF(result == ERROR_SUCCESS, (_T("error = %d\n"), result));
  36. if (result != ERROR_SUCCESS)
  37. {
  38. return result;
  39. }
  40. ASSERT(path_key != 0);
  41. first_counter = 0;
  42. DWORD ctr_size = sizeof(DWORD);
  43. result = RegQueryValueEx(path_key, _T("First Counter"), 0, 0,
  44. (BYTE *)&first_counter, &ctr_size);
  45. ASSERT_PRINTF(result == ERROR_SUCCESS, (_T("error = %d\n"), result));
  46. if (result != ERROR_SUCCESS)
  47. {
  48. RegCloseKey(path_key);
  49. return result;
  50. }
  51. first_help = 0;
  52. ctr_size = sizeof(DWORD);
  53. result = RegQueryValueEx(path_key, _T("First Help"), 0, 0,
  54. (BYTE *)&first_help, &ctr_size);
  55. ASSERT_PRINTF(result == ERROR_SUCCESS, (_T("error = %d\n"), result));
  56. if (result != ERROR_SUCCESS)
  57. {
  58. RegCloseKey(path_key);
  59. return result;
  60. }
  61. ASSERT(path_key != 0);
  62. RegCloseKey(path_key);
  63. path_key = 0;
  64. }
  65. open_count++;
  66. return ERROR_SUCCESS;
  67. }
  68. extern "C" DWORD WINAPI CloseGrovelerPerformanceData()
  69. {
  70. ASSERT(open_count > 0);
  71. open_count--;
  72. if (open_count == 0)
  73. {
  74. ASSERT(shared_data != NULL);
  75. delete shared_data;
  76. shared_data = NULL;
  77. }
  78. return ERROR_SUCCESS;
  79. }
  80. extern "C" DWORD WINAPI CollectGrovelerPerformanceData(
  81. LPWSTR lpwszValue,
  82. LPVOID *lppData,
  83. LPDWORD lpcbBytes,
  84. LPDWORD lpcObjectTypes)
  85. {
  86. if (open_count == 0)
  87. {
  88. *lpcbBytes = 0;
  89. *lpcObjectTypes = 0;
  90. return ERROR_SUCCESS;
  91. }
  92. int num_partitions;
  93. SharedDataRecord records[max_shared_data_records];
  94. bool ok = shared_data->extract_values(&num_partitions, records);
  95. if (!ok)
  96. {
  97. *lpcbBytes = 0;
  98. *lpcObjectTypes = 0;
  99. return ERROR_SUCCESS;
  100. }
  101. int data_size = space_needed_for_data(num_partitions);
  102. if (data_size > int(*lpcbBytes))
  103. {
  104. *lpcbBytes = 0;
  105. *lpcObjectTypes = 0;
  106. return ERROR_MORE_DATA;
  107. }
  108. build_part_object_info_block(lppData, num_partitions, data_size);
  109. for (int index = 0; index < num_partitions; index++)
  110. {
  111. build_part_instance_info_block(lppData, index, records);
  112. }
  113. if (num_partitions > 0)
  114. {
  115. build_total_instance_info_block(lppData, num_partitions, records);
  116. }
  117. *lpcbBytes = data_size;
  118. *lpcObjectTypes = 1;
  119. return ERROR_SUCCESS;
  120. }
  121. int space_needed_for_data(
  122. int num_partitions)
  123. {
  124. if (num_partitions > 0)
  125. {
  126. return sizeof(PartitionObjectInformationBlock) +
  127. num_partitions * sizeof(PartitionInstanceInformationBlock) +
  128. sizeof(TotalInstanceInformationBlock);
  129. }
  130. else
  131. {
  132. return sizeof(PartitionObjectInformationBlock);
  133. }
  134. }
  135. void build_part_object_info_block(
  136. LPVOID *lppData,
  137. int num_partitions,
  138. int data_size)
  139. {
  140. int num_instances = 0;
  141. if (num_partitions > 0)
  142. {
  143. num_instances = num_partitions + 1;
  144. }
  145. PartitionObjectInformationBlock *block =
  146. (PartitionObjectInformationBlock *)*lppData;
  147. block->object_type.TotalByteLength = data_size;
  148. block->object_type.DefinitionLength =
  149. sizeof(PartitionObjectInformationBlock);
  150. block->object_type.HeaderLength = sizeof(PERF_OBJECT_TYPE);
  151. block->object_type.ObjectNameTitleIndex = first_counter;
  152. block->object_type.ObjectNameTitle = 0;
  153. block->object_type.ObjectHelpTitleIndex = first_help;
  154. block->object_type.ObjectHelpTitle = 0;
  155. block->object_type.DetailLevel = object_info.detail_level;
  156. block->object_type.NumCounters = num_perf_counters;
  157. block->object_type.DefaultCounter = 0;
  158. block->object_type.NumInstances = num_instances;
  159. block->object_type.CodePage = 0;
  160. for (int index = 0; index < num_perf_counters; index++)
  161. {
  162. block->definition[index].ByteLength = sizeof(PERF_COUNTER_DEFINITION);
  163. block->definition[index].CounterNameTitleIndex =
  164. first_counter + 2 * (index + 1);
  165. block->definition[index].CounterNameTitle = 0;
  166. block->definition[index].CounterHelpTitleIndex =
  167. first_help + 2 * (index + 1);
  168. block->definition[index].CounterHelpTitle = 0;
  169. block->definition[index].DefaultScale = 0;
  170. block->definition[index].DetailLevel = counter_info[index].detail_level;
  171. block->definition[index].CounterType = counter_info[index].counter_type;
  172. block->definition[index].CounterSize = sizeof(LARGE_INTEGER);
  173. block->definition[index].CounterOffset =
  174. FIELD_OFFSET( PartitionData, counter[index] );
  175. }
  176. *lppData = (void *)(block + 1);
  177. }
  178. void build_part_instance_info_block(
  179. LPVOID *lppData,
  180. int partition_index,
  181. SharedDataRecord *records)
  182. {
  183. PartitionInstanceInformationBlock *block =
  184. (PartitionInstanceInformationBlock *)*lppData;
  185. block->instance_def.ByteLength =
  186. FIELD_OFFSET(PartitionInstanceInformationBlock, partition_data);
  187. block->instance_def.ParentObjectTitleIndex = 0;
  188. block->instance_def.ParentObjectInstance = 0;
  189. block->instance_def.UniqueID = PERF_NO_UNIQUE_ID;
  190. block->instance_def.NameOffset =
  191. FIELD_OFFSET(PartitionInstanceInformationBlock, instance_name);
  192. block->instance_def.NameLength =
  193. sizeof(_TCHAR) * (partition_name_length);
  194. (void)StringCbPrintf(block->instance_name, sizeof(block->instance_name), _T("%-.*s"),
  195. partition_name_length,
  196. records[partition_index].driveName);
  197. block->partition_data.counter_block.ByteLength = sizeof(PartitionData);
  198. for (int index = 0; index < num_perf_counters; index++)
  199. {
  200. switch (counter_info[index].counter_type)
  201. {
  202. case PERF_100NSEC_TIMER:
  203. block->partition_data.counter[index].QuadPart = ms_per_100ns_inv *
  204. records[partition_index].fields[counter_info[index].source];
  205. break;
  206. default:
  207. block->partition_data.counter[index].QuadPart =
  208. records[partition_index].fields[counter_info[index].source];
  209. break;
  210. }
  211. }
  212. *lppData = (void *)(block + 1);
  213. }
  214. void build_total_instance_info_block(
  215. LPVOID *lppData,
  216. int num_partitions,
  217. SharedDataRecord *records)
  218. {
  219. TotalInstanceInformationBlock *block =
  220. (TotalInstanceInformationBlock *)*lppData;
  221. block->instance_def.ByteLength =
  222. FIELD_OFFSET(TotalInstanceInformationBlock, partition_data);
  223. block->instance_def.ParentObjectTitleIndex = 0;
  224. block->instance_def.ParentObjectInstance = 0;
  225. block->instance_def.UniqueID = PERF_NO_UNIQUE_ID;
  226. block->instance_def.NameOffset =
  227. FIELD_OFFSET(TotalInstanceInformationBlock, instance_name);
  228. block->instance_def.NameLength =
  229. sizeof(_TCHAR) * (total_name_length);
  230. _tcscpy(block->instance_name, _T("_Total"));
  231. block->partition_data.counter_block.ByteLength = sizeof(PartitionData);
  232. for (int index = 0; index < num_perf_counters; index++)
  233. {
  234. total_counter[index] = 0;
  235. }
  236. for (int part = 0; part < num_partitions; part++)
  237. {
  238. for (index = 0; index < num_perf_counters; index++)
  239. {
  240. total_counter[index] +=
  241. records[part].fields[counter_info[index].source];
  242. }
  243. }
  244. for (index = 0; index < num_perf_counters; index++)
  245. {
  246. switch (counter_info[index].counter_type)
  247. {
  248. case PERF_100NSEC_TIMER:
  249. block->partition_data.counter[index].QuadPart =
  250. ms_per_100ns_inv * total_counter[index];
  251. break;
  252. default:
  253. block->partition_data.counter[index].QuadPart =
  254. total_counter[index];
  255. break;
  256. }
  257. }
  258. *lppData = (void *)(block + 1);
  259. }