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.

449 lines
16 KiB

  1. #define _PassportExport_
  2. #include "PassportExport.h"
  3. #include "PerfSharedMemory.h"
  4. #include "PerfUtils.h"
  5. #include "PassportPerf.h"
  6. #include "PassportPerfInterface.h"
  7. #include <crtdbg.h>
  8. //-------------------------------------------------------------
  9. //
  10. // PerfSharedMemory
  11. //
  12. //-------------------------------------------------------------
  13. PerfSharedMemory::PerfSharedMemory() : PassportSharedMemory()
  14. {
  15. m_dwNumCounters = 0;
  16. }
  17. //-------------------------------------------------------------
  18. //
  19. // PerfSharedMemory
  20. //
  21. //-------------------------------------------------------------
  22. PerfSharedMemory::~PerfSharedMemory()
  23. {
  24. }
  25. //-------------------------------------------------------------
  26. //
  27. // initialize
  28. //
  29. //-------------------------------------------------------------
  30. BOOL PerfSharedMemory::initialize(
  31. const DWORD &dwNumCounters,
  32. const DWORD &dwFirstCounter,
  33. const DWORD &dwFirstHelp)
  34. {
  35. if ( dwNumCounters <= 0 || dwNumCounters >= PassportPerfInterface::MAX_COUNTERS)
  36. return FALSE;
  37. m_dwNumCounters = dwNumCounters;
  38. // 2. initialize the PERF_OBJECT_TYPE
  39. m_Object.NumInstances = PassportPerfInterface::MAX_INSTANCES;
  40. m_Object.TotalByteLength = 0;
  41. m_Object.DefinitionLength = sizeof(PERF_OBJECT_TYPE)
  42. + (dwNumCounters * sizeof(PERF_COUNTER_DEFINITION));
  43. m_Object.HeaderLength = sizeof(PERF_OBJECT_TYPE);
  44. m_Object.ObjectNameTitleIndex = dwFirstCounter;
  45. m_Object.ObjectNameTitle = 0;
  46. m_Object.ObjectHelpTitleIndex = dwFirstHelp;
  47. m_Object.ObjectHelpTitle = 0;
  48. m_Object.DetailLevel = PERF_DETAIL_NOVICE;
  49. m_Object.NumCounters = dwNumCounters;
  50. m_Object.DefaultCounter = 0;
  51. m_Object.CodePage = 0;
  52. // 3. initialize each counter
  53. for (DWORD i = 0; i < dwNumCounters; i++)
  54. {
  55. m_Counter[i].ByteLength = sizeof(PERF_COUNTER_DEFINITION);
  56. m_Counter[i].CounterNameTitleIndex = dwFirstCounter + ((i+1) * 2);
  57. m_Counter[i].CounterNameTitle = 0;
  58. m_Counter[i].CounterHelpTitleIndex = dwFirstHelp + ((i+1) * 2);
  59. m_Counter[i].CounterHelpTitle = 0;
  60. m_Counter[i].DefaultScale = 0;
  61. m_Counter[i].DetailLevel = PERF_DETAIL_NOVICE;
  62. m_Counter[i].CounterType = PERF_COUNTER_RAWCOUNT; // PERF_COUNTER_COUNTER;
  63. m_Counter[i].CounterSize = sizeof(DWORD);
  64. m_Counter[i].CounterOffset = sizeof(PERF_COUNTER_BLOCK) + (i * sizeof(DWORD));
  65. }
  66. return TRUE;
  67. }
  68. //-------------------------------------------------------------
  69. //
  70. // setDefaultCounterType
  71. //
  72. //-------------------------------------------------------------
  73. VOID PerfSharedMemory::setDefaultCounterType (
  74. const DWORD dwIndex,
  75. const DWORD dwType )
  76. {
  77. _ASSERT( (dwIndex >= 0) && (dwIndex < PassportPerfInterface::MAX_COUNTERS));
  78. // indexes start at one in SHM, but in this object they start at 0
  79. DWORD dwRealIndex = ((dwIndex == 0) ? 0 : (DWORD)(dwIndex/2)-1);
  80. m_Counter[dwRealIndex].CounterType = dwType;
  81. return;
  82. }
  83. //-------------------------------------------------------------
  84. //
  85. // checkQuery
  86. //
  87. //-------------------------------------------------------------
  88. BOOL PerfSharedMemory::checkQuery ( const LPWSTR lpValueName )
  89. {
  90. DWORD dwQueryType = 0;
  91. dwQueryType = GetQueryType (lpValueName);
  92. if (dwQueryType == QUERY_FOREIGN)
  93. {
  94. // this routine does not service requests for data from
  95. // Non-NT computers
  96. return FALSE;
  97. }
  98. if (dwQueryType == QUERY_ITEMS)
  99. {
  100. if ( !(IsNumberInUnicodeList (m_Object.ObjectNameTitleIndex, lpValueName)))
  101. {
  102. // request received for data object not provided by this routine
  103. return FALSE;
  104. }
  105. }
  106. return TRUE;
  107. }
  108. //-------------------------------------------------------------
  109. //
  110. // spaceNeeded
  111. //
  112. //-------------------------------------------------------------
  113. ULONG PerfSharedMemory::spaceNeeded ( void )
  114. {
  115. DWORD dwTotalInstanceLength = 0;
  116. m_Object.NumInstances = 0;
  117. // --------------------------------
  118. // count the instances
  119. if (m_pbShMem != NULL)
  120. {
  121. BYTE* pShm = (BYTE *)m_pbShMem;
  122. if (pShm != NULL)
  123. {
  124. pShm += PassportPerfInterface::MAX_COUNTERS * sizeof(DWORD);
  125. if (!m_bUseMutex
  126. || WaitForSingleObject(m_hMutex,INFINITE) == WAIT_OBJECT_0)
  127. {
  128. for (DWORD i = 0; i < PassportPerfInterface::MAX_INSTANCES; i++)
  129. {
  130. INSTANCE_DATA * pInst = (INSTANCE_DATA *)pShm;
  131. _ASSERT(pInst);
  132. if (pInst->active)
  133. {
  134. m_Object.NumInstances++;
  135. dwTotalInstanceLength += (strlen(pInst->szInstanceName)+1) * sizeof(WCHAR);
  136. }
  137. pShm += sizeof(INSTANCE_DATA) +
  138. (PassportPerfInterface::MAX_COUNTERS * sizeof(DWORD));
  139. }
  140. if (m_bUseMutex)
  141. ReleaseMutex(m_hMutex);
  142. }
  143. else
  144. {
  145. //
  146. // The return value is ULONG not FALSE.
  147. // Is 0 correct here? At least same value as the old FALSE.
  148. //
  149. ReleaseMutex(m_hMutex);
  150. return 0;
  151. }
  152. }
  153. }
  154. // --------------------------------
  155. // calculate the ByteLength in the Object structure
  156. if (m_Object.NumInstances == 0)
  157. {
  158. m_Object.NumInstances = PERF_NO_INSTANCES;
  159. m_Object.TotalByteLength = sizeof(PERF_OBJECT_TYPE)
  160. + (m_dwNumCounters * sizeof(PERF_COUNTER_DEFINITION))
  161. + sizeof(PERF_COUNTER_BLOCK)
  162. + (m_dwNumCounters * sizeof(DWORD));
  163. }
  164. else
  165. {
  166. m_Object.TotalByteLength = sizeof(PERF_OBJECT_TYPE)
  167. + (m_dwNumCounters * sizeof(PERF_COUNTER_DEFINITION))
  168. + (m_Object.NumInstances *
  169. (sizeof(PERF_INSTANCE_DEFINITION) +
  170. // note: INSTANCENAME is next in the SHM
  171. sizeof(PERF_COUNTER_BLOCK) +
  172. (m_dwNumCounters * sizeof(DWORD)) ))
  173. + dwTotalInstanceLength;
  174. }
  175. // align on 8 bytes boundary ...
  176. if (m_Object.TotalByteLength & 7)
  177. {
  178. m_Object.TotalByteLength += 8;
  179. m_Object.TotalByteLength &= ~7;
  180. }
  181. return m_Object.TotalByteLength;
  182. }
  183. //-------------------------------------------------------------
  184. //
  185. // writeData
  186. //
  187. //-------------------------------------------------------------
  188. BOOL PerfSharedMemory::writeData (
  189. LPVOID *lppData,
  190. LPDWORD lpcbTotalBytes )
  191. {
  192. BYTE* pb = NULL;
  193. DWORD dwBytes = 0;
  194. // --------------------------------
  195. // 1. find the active number of instances
  196. // (may have been done already)
  197. if (m_Object.TotalByteLength == 0)
  198. spaceNeeded();
  199. pb = (BYTE*) *lppData;
  200. // --------------------------------
  201. // 2. copy the Object structure
  202. CopyMemory( pb, &m_Object, sizeof(PERF_OBJECT_TYPE) );
  203. pb += sizeof(PERF_OBJECT_TYPE);
  204. dwBytes += sizeof(PERF_OBJECT_TYPE);
  205. if (!m_bUseMutex
  206. || WaitForSingleObject(m_hMutex,INFINITE) == WAIT_OBJECT_0)
  207. {
  208. // --------------------------------
  209. // 3. read the counter types from SHM
  210. if ( m_pbShMem != NULL )
  211. {
  212. DWORD dwPerfType = 0;
  213. BYTE * pShm = (BYTE*)m_pbShMem;
  214. _ASSERT(pShm);
  215. for (DWORD j = 0; j < m_dwNumCounters; j++)
  216. {
  217. PDWORD pdwCounter = ((PDWORD) pShm) + j;
  218. _ASSERT(pdwCounter);
  219. // only reset the counter if it has a defined value
  220. // or if it has changed
  221. if (*pdwCounter != PERF_TYPE_ZERO
  222. && m_Counter[j].CounterType != *pdwCounter)
  223. m_Counter[j].CounterType = (*pdwCounter);
  224. }
  225. }
  226. // --------------------------------
  227. // 4. copy the counters
  228. for (DWORD i = 0; i < m_dwNumCounters; i++)
  229. {
  230. CopyMemory( pb, &(m_Counter[i]),sizeof(PERF_COUNTER_DEFINITION));
  231. pb += sizeof(PERF_COUNTER_DEFINITION);
  232. dwBytes += sizeof(PERF_COUNTER_DEFINITION);
  233. }
  234. // --------------------------------
  235. // 5. if SHM if null, then just dump out all
  236. // zeroes for the counters
  237. if ( m_pbShMem == NULL )
  238. {
  239. // copy the number of counters in the counter block
  240. PERF_COUNTER_BLOCK counterBlock;
  241. counterBlock.ByteLength = sizeof(PERF_COUNTER_BLOCK) +
  242. (m_dwNumCounters * sizeof(DWORD));
  243. CopyMemory( pb, &counterBlock, sizeof(PERF_COUNTER_BLOCK));
  244. pb += sizeof(PERF_COUNTER_BLOCK);
  245. dwBytes += sizeof(PERF_COUNTER_BLOCK);
  246. for (DWORD j = 1; j <= m_dwNumCounters; j++)
  247. {
  248. DWORD val = 0;
  249. CopyMemory( pb, &val, sizeof(DWORD));
  250. pb += sizeof(DWORD);
  251. dwBytes += sizeof(DWORD);
  252. }
  253. }
  254. // --------------------------------
  255. // 6. if object has no instances, then read just the first
  256. // section of data,
  257. else if (m_Object.NumInstances == PERF_NO_INSTANCES)
  258. {
  259. _ASSERT(m_pbShMem);
  260. BYTE * pShm = (BYTE*)m_pbShMem;
  261. _ASSERT(pShm);
  262. pShm += (PassportPerfInterface::MAX_COUNTERS * sizeof(DWORD));
  263. pShm += sizeof(INSTANCE_DATA);
  264. _ASSERT(pShm);
  265. // copy the number of counters in the counter block
  266. PERF_COUNTER_BLOCK counterBlock;
  267. counterBlock.ByteLength = sizeof(PERF_COUNTER_BLOCK) +
  268. (m_dwNumCounters * sizeof(DWORD));
  269. CopyMemory( pb, &counterBlock, sizeof(PERF_COUNTER_BLOCK));
  270. pb += sizeof(PERF_COUNTER_BLOCK);
  271. dwBytes += sizeof(PERF_COUNTER_BLOCK);
  272. PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)pShm;
  273. _ASSERT(pCounterBlock);
  274. for (DWORD j = 1; j <= m_dwNumCounters; j++)
  275. {
  276. PDWORD pdwCounter = ((PDWORD) pCounterBlock) + j;
  277. _ASSERT(pdwCounter);
  278. DWORD val = *pdwCounter;
  279. CopyMemory( pb, &val, sizeof(DWORD));
  280. pb += sizeof(DWORD);
  281. dwBytes += sizeof(DWORD);
  282. }
  283. }
  284. // --------------------------------
  285. // 7. get and write all instance data
  286. else
  287. {
  288. _ASSERT(m_pbShMem);
  289. BYTE * pShm = (BYTE*)m_pbShMem;
  290. _ASSERT(pShm);
  291. pShm += (PassportPerfInterface::MAX_COUNTERS * sizeof(DWORD));
  292. DWORD dwInstanceIndex = 0;
  293. for (i = 0; i < (DWORD)m_Object.NumInstances; i++)
  294. {
  295. PERF_INSTANCE_DEFINITION instDef;
  296. PERF_COUNTER_BLOCK perfCounterBlock;
  297. BOOL gotInstance = FALSE;
  298. INSTANCE_DATA * pInst = NULL;
  299. WCHAR wszName[MAX_PATH];
  300. // 7a. get the instance name from the next active instance
  301. // in SHM
  302. for (DWORD i = dwInstanceIndex;
  303. i < PassportPerfInterface::MAX_INSTANCES && !gotInstance;
  304. i++)
  305. {
  306. pInst = (INSTANCE_DATA *)pShm;
  307. _ASSERT(pInst);
  308. pShm += sizeof(INSTANCE_DATA);
  309. if (pInst->active)
  310. {
  311. dwInstanceIndex = i + 1;
  312. gotInstance = TRUE;
  313. }
  314. else
  315. {
  316. pShm += (PassportPerfInterface::MAX_COUNTERS * sizeof(DWORD));
  317. }
  318. }
  319. if (!gotInstance || pInst == NULL)
  320. return FALSE;
  321. // 7b. create the instace Definition and
  322. // copy it (also get the instance name)
  323. instDef.ParentObjectTitleIndex = 0;//m_Object.ObjectNameTitleIndex + 2*i;
  324. instDef.ParentObjectInstance = 0; // ????
  325. instDef.UniqueID = PERF_NO_UNIQUE_ID;
  326. instDef.NameOffset = sizeof(PERF_INSTANCE_DEFINITION);
  327. // Build UNICODE instance name
  328. if (!MultiByteToWideChar( CP_ACP,
  329. MB_PRECOMPOSED,
  330. pInst->szInstanceName,
  331. strlen(pInst->szInstanceName)+1,
  332. wszName,
  333. MAX_PATH))
  334. {
  335. wszName[0] = 0;
  336. }
  337. instDef.NameLength = (lstrlenW( wszName ) + 1) * sizeof(WCHAR);
  338. instDef.ByteLength = sizeof(PERF_INSTANCE_DEFINITION)
  339. + instDef.NameLength;
  340. CopyMemory( pb, &instDef, sizeof(PERF_INSTANCE_DEFINITION) );
  341. pb += sizeof(PERF_INSTANCE_DEFINITION);
  342. dwBytes += sizeof(PERF_INSTANCE_DEFINITION);
  343. // 7c. copy the instance name
  344. CopyMemory(pb, wszName, instDef.NameLength);
  345. pb += instDef.NameLength;
  346. dwBytes += instDef.NameLength;
  347. // 7d. copy the counterblock
  348. perfCounterBlock.ByteLength = sizeof(PERF_COUNTER_BLOCK)
  349. + (m_dwNumCounters * sizeof(DWORD));
  350. CopyMemory( pb, &perfCounterBlock, sizeof(PERF_COUNTER_BLOCK));
  351. pb += sizeof(PERF_COUNTER_BLOCK);
  352. dwBytes += sizeof(PERF_COUNTER_BLOCK);
  353. // 7e. copy the DWORDs themselves
  354. PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)pShm;
  355. DWORD val = 0;
  356. for (DWORD j = 1; j <= m_dwNumCounters; j++)
  357. {
  358. if (m_pbShMem != NULL)
  359. {
  360. PDWORD pdwCounter = ((PDWORD) pCounterBlock) + j;
  361. val = *pdwCounter;
  362. }
  363. CopyMemory( pb, &val, sizeof(DWORD));
  364. pb += sizeof(DWORD);
  365. dwBytes += sizeof(DWORD);
  366. }
  367. pShm += (PassportPerfInterface::MAX_COUNTERS * sizeof(DWORD));
  368. } // end for ( i = ...)
  369. } // end else (instances exist)
  370. if (m_bUseMutex)
  371. ReleaseMutex(m_hMutex);
  372. }
  373. else
  374. {
  375. ReleaseMutex(m_hMutex);
  376. return FALSE;
  377. }
  378. //
  379. // 8 byte alignment
  380. while (dwBytes%8 != 0)
  381. {
  382. (dwBytes)++;
  383. pb++;
  384. }
  385. *lppData = (void*) pb;//++pb;
  386. *lpcbTotalBytes = dwBytes;
  387. return TRUE;
  388. }