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.

442 lines
13 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1999
  5. //
  6. // File: IdqPerf.hxx
  7. //
  8. // Contents: Perfmon counters for ISAPI search engine.
  9. //
  10. // History: 15-Mar-1996 KyleP Created (from perfci.hxx)
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <pch.cxx>
  14. #pragma hdrstop
  15. #include <idqperf.hxx>
  16. #include <smem.hxx>
  17. #include "prfutil.hxx"
  18. //
  19. // For Ci - ISAPI HTTP
  20. //
  21. CI_ISAPI_DATA_DEFINITION CIISAPIDataDefinition = {
  22. { sizeof(CI_ISAPI_DATA_DEFINITION) +
  23. CI_ISAPI_SIZE_OF_COUNTER_BLOCK, // Total Bytes ( Size of this header, the counter definitions
  24. // and the size of the actual counter data )
  25. sizeof(CI_ISAPI_DATA_DEFINITION),// Definition length ( This header and the counter definitions )
  26. sizeof(PERF_OBJECT_TYPE), // Header Length ( This header )
  27. CIISAPIOBJECT, // Object Name Title Index
  28. 0, // Object Name Title
  29. CIISAPIOBJECT, // Object Help Title Index
  30. 0, // Object Help Title
  31. PERF_DETAIL_NOVICE, // Detail Level
  32. CI_ISAPI_TOTAL_NUM_COUNTERS, // Number of Counters
  33. 1, // Default Counters
  34. PERF_NO_INSTANCES, // Num Instances
  35. 0, // Code Page
  36. {0,0}, // Perf Time
  37. {0,0} // Perf Freq
  38. },
  39. { sizeof(PERF_COUNTER_DEFINITION), // Number of cache items
  40. NUM_CACHE_ITEMS,
  41. 0,
  42. NUM_CACHE_ITEMS,
  43. 0,
  44. 0,
  45. PERF_DETAIL_NOVICE,
  46. PERF_COUNTER_RAWCOUNT,
  47. sizeof(DWORD),
  48. NUM_CACHE_ITEMS_OFF
  49. },
  50. { sizeof(PERF_COUNTER_DEFINITION), // Number of cache hits
  51. NUM_CACHE_HITS,
  52. 0,
  53. NUM_CACHE_HITS,
  54. 0,
  55. -1,
  56. PERF_DETAIL_NOVICE,
  57. PERF_RAW_FRACTION,
  58. sizeof(DWORD),
  59. NUM_CACHE_HITS_OFF
  60. },
  61. { sizeof(PERF_COUNTER_DEFINITION), // Base for number of cache hits
  62. NUM_CACHE_HITS_AND_MISSES_1,
  63. 0,
  64. NUM_CACHE_HITS_AND_MISSES_1,
  65. 0,
  66. -1,
  67. PERF_DETAIL_NOVICE,
  68. PERF_RAW_BASE,
  69. sizeof(DWORD),
  70. NUM_CACHE_HITS_AND_MISSES_OFF
  71. },
  72. { sizeof(PERF_COUNTER_DEFINITION), // Number of cache misses
  73. NUM_CACHE_MISSES,
  74. 0,
  75. NUM_CACHE_MISSES,
  76. 0,
  77. 0,
  78. PERF_DETAIL_NOVICE,
  79. PERF_RAW_FRACTION,
  80. sizeof(DWORD),
  81. NUM_CACHE_MISSES_OFF
  82. },
  83. { sizeof(PERF_COUNTER_DEFINITION), // Base for number of cache hits
  84. NUM_CACHE_HITS_AND_MISSES_2,
  85. 0,
  86. NUM_CACHE_HITS_AND_MISSES_2,
  87. 0,
  88. -1,
  89. PERF_DETAIL_NOVICE,
  90. PERF_RAW_BASE,
  91. sizeof(DWORD),
  92. NUM_CACHE_HITS_AND_MISSES_OFF
  93. },
  94. { sizeof(PERF_COUNTER_DEFINITION), // Number of running queries
  95. NUM_RUNNING_QUERIES,
  96. 0,
  97. NUM_RUNNING_QUERIES,
  98. 0,
  99. 0,
  100. PERF_DETAIL_NOVICE,
  101. PERF_COUNTER_RAWCOUNT,
  102. sizeof(DWORD),
  103. NUM_RUNNING_QUERIES_OFF
  104. },
  105. { sizeof(PERF_COUNTER_DEFINITION), // Total queries
  106. NUM_TOTAL_QUERIES,
  107. 0,
  108. NUM_TOTAL_QUERIES,
  109. 0,
  110. 0,
  111. PERF_DETAIL_NOVICE,
  112. PERF_COUNTER_RAWCOUNT,
  113. sizeof(DWORD),
  114. NUM_TOTAL_QUERIES_OFF
  115. },
  116. { sizeof(PERF_COUNTER_DEFINITION), // Number of queries per minute
  117. NUM_QUERIES_PER_MINUTE,
  118. 0,
  119. NUM_QUERIES_PER_MINUTE,
  120. 0,
  121. 0,
  122. PERF_DETAIL_NOVICE,
  123. PERF_COUNTER_RAWCOUNT,
  124. sizeof(DWORD),
  125. NUM_QUERIES_PER_MINUTE_OFF
  126. },
  127. { sizeof(PERF_COUNTER_DEFINITION), // Current # of queued requests
  128. NUM_REQUESTS_QUEUED,
  129. 0,
  130. NUM_REQUESTS_QUEUED,
  131. 0,
  132. 0,
  133. PERF_DETAIL_NOVICE,
  134. PERF_COUNTER_RAWCOUNT,
  135. sizeof(DWORD),
  136. NUM_REQUESTS_QUEUED_OFF
  137. },
  138. { sizeof(PERF_COUNTER_DEFINITION), // Total # of rejected requests
  139. NUM_REQUESTS_REJECTED,
  140. 0,
  141. NUM_REQUESTS_REJECTED,
  142. 0,
  143. 0,
  144. PERF_DETAIL_NOVICE,
  145. PERF_COUNTER_RAWCOUNT,
  146. sizeof(DWORD),
  147. NUM_REQUESTS_REJECTED_OFF
  148. }
  149. };
  150. CNamedSharedMem TheMem;
  151. WCHAR const CIISAPIPerformanceKeyName[] =
  152. TEXT("SYSTEM\\CurrentControlSet\\Services\\ISAPISearch\\Performance");
  153. WCHAR const FirstCounterKeyName [] = TEXT("First Counter");
  154. WCHAR const FirstHelpKeyName [] = TEXT("First Help");
  155. //+---------------------------------------------------------------------------
  156. //
  157. // Function: InitializeCIISAPIerformanceData
  158. //
  159. // Purpose: Build and initialize the performance data structure.
  160. //
  161. // Arguments: [pInstance] -- dummy variable
  162. //
  163. // History: 15-Mar-96 KyleP Created
  164. //
  165. //----------------------------------------------------------------------------
  166. DWORD InitializeCIISAPIPerformanceData( LPWSTR pInstance )
  167. {
  168. //
  169. // Some apps open perfmon keys more than once and Done() doesn't
  170. // free any resources, do don't bother refcounting.
  171. //
  172. static BOOL fInit = FALSE;
  173. if ( fInit )
  174. return NO_ERROR;
  175. CTranslateSystemExceptions translate;
  176. TRY
  177. {
  178. if ( !TheMem.Ok() )
  179. TheMem.OpenForRead( CI_ISAPI_PERF_SHARED_MEM );
  180. //
  181. // If no IDQ queries have been issued, there will be no memory, but
  182. // don't fail the initialize; just return 0 data in Collect().
  183. // This (apparently) is the intended design of perfmon.
  184. //
  185. if ( 0 == TheMem.GetPointer() )
  186. return NO_ERROR; //the collect function will just return no data
  187. }
  188. CATCH( CException, e )
  189. {
  190. return NO_ERROR; // the collect function will just return no data
  191. }
  192. END_CATCH;
  193. //
  194. // Open the registry which contain the last key's index
  195. //
  196. HKEY hKeyPerf = 0;
  197. LONG status = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  198. CIISAPIPerformanceKeyName,
  199. 0L,
  200. KEY_READ,
  201. &hKeyPerf );
  202. if (status != ERROR_SUCCESS)
  203. {
  204. RegCloseKey( hKeyPerf );
  205. //ciGibDebugOut(( DEB_ERROR, "Error in RegOpenKeyEx\n"));
  206. return status;
  207. }
  208. //
  209. // Get the index of the first counter
  210. //
  211. DWORD type;
  212. DWORD dwFirstCounter;
  213. DWORD size = sizeof dwFirstCounter;
  214. status = RegQueryValueEx( hKeyPerf, FirstCounterKeyName, 0L, &type,
  215. (LPBYTE)&dwFirstCounter, &size);
  216. if (status != ERROR_SUCCESS)
  217. {
  218. //ciGibDebugOut(( DEB_ERROR, "Error in Query First Counter\n"));
  219. RegCloseKey( hKeyPerf );
  220. return status;
  221. }
  222. //
  223. // Get the index of the first help
  224. //
  225. DWORD dwFirstHelp;
  226. size = sizeof dwFirstHelp;
  227. status = RegQueryValueEx( hKeyPerf, FirstHelpKeyName,
  228. 0L, &type, (LPBYTE)&dwFirstHelp, &size );
  229. if (status != ERROR_SUCCESS)
  230. {
  231. //ciGibDebugOut(( DEB_ERROR, "Error in Query First Help Key\n"));
  232. RegCloseKey( hKeyPerf );
  233. return status;
  234. }
  235. //
  236. // Update the index of both title and help of each counter
  237. //
  238. CIISAPIDataDefinition.CIISAPIObjectType.ObjectNameTitleIndex += dwFirstCounter;
  239. CIISAPIDataDefinition.CIISAPIObjectType.ObjectHelpTitleIndex += dwFirstHelp;
  240. PERF_COUNTER_DEFINITION * pTmp = (PERF_COUNTER_DEFINITION *) ((BYTE *)&CIISAPIDataDefinition
  241. + sizeof(PERF_OBJECT_TYPE) );
  242. for ( unsigned i = 0;
  243. i < CIISAPIDataDefinition.CIISAPIObjectType.NumCounters;
  244. i++ )
  245. {
  246. pTmp->CounterNameTitleIndex += dwFirstCounter;
  247. pTmp->CounterHelpTitleIndex += dwFirstHelp;
  248. pTmp++;
  249. }
  250. //
  251. // Close the registry key
  252. //
  253. RegCloseKey( hKeyPerf );
  254. //
  255. // set the flag to TRUE
  256. //
  257. //ciGibDebugOut((DEB_ITRACE, "InitializeFilterPerformanceData : Done\n" ));
  258. fInit = TRUE;
  259. return ERROR_SUCCESS;
  260. } //InitializeCIISAPIPerformanceData
  261. //+---------------------------------------------------------------------------
  262. //
  263. // Function : CollectCIISAPIPerformanceData
  264. //
  265. // Purpose : Collect Performance Data of Content Index to PerfMon
  266. //
  267. // Arguments:
  268. // [lpValueName] -- pointer to a wide character string passed by registry
  269. //
  270. // [lppData] -- IN: pointer to the address of the buffer to receive the
  271. // completed PerfDataBlock and subordinate structures. This
  272. // routine will append its data to the buffer starting at
  273. // the point referenced by *lppData.
  274. //
  275. // OUT: points to the first byte after the data structure
  276. // added by this routine. This routine updated the value at
  277. // lppdata after appending its data.
  278. //
  279. // [lpcbTotalBytes] -- IN: the address of the DWORD that tells the size in bytes
  280. // of the buffer referenced by the lppData argument
  281. //
  282. // OUT: the number of bytes added by this routine is written
  283. // to the DWORD pointed to by this argument
  284. //
  285. // [lpNumObjectTypes] -- IN: the address of the DWORD to receive the number of
  286. // objects added by this routine
  287. //
  288. // OUT: the number of objects added by this routine is written
  289. // to the DWORD pointed to by this argument
  290. //
  291. // History : 23-March-94 t-joshh Created
  292. //
  293. // Return : ERROR_MORE_DATA if the size of the input buffer is too small
  294. // ERROR_SUCCESS if success
  295. //----------------------------------------------------------------------------
  296. DWORD CollectCIISAPIPerformanceData( LPWSTR lpValueName,
  297. LPVOID *lppData,
  298. LPDWORD lpcbTotalBytes,
  299. LPDWORD lpNumObjectTypes )
  300. {
  301. //
  302. // see if this is a foreign (i.e. non-NT) computer data request
  303. //
  304. DWORD dwQueryType = GetQueryType (lpValueName);
  305. if ( ( QUERY_FOREIGN == dwQueryType ) ||
  306. ( !TheMem.Ok() ) )
  307. {
  308. //
  309. // This routine does not service requests for data from
  310. // Non-NT computers. Or if Init() failed.
  311. //
  312. *lpcbTotalBytes = (DWORD) 0;
  313. *lpNumObjectTypes = (DWORD) 0;
  314. return( ERROR_SUCCESS );
  315. }
  316. //
  317. // If the caller only wanted some counter, check if we have them
  318. //
  319. if ( dwQueryType == QUERY_ITEMS )
  320. {
  321. WCHAR wcsNum[50];
  322. _ultow( CIISAPIDataDefinition.CIISAPIObjectType.ObjectNameTitleIndex,
  323. wcsNum,
  324. 10 );
  325. if ( 0 == wcsstr( lpValueName, wcsNum ) )
  326. {
  327. //
  328. // request received for data object not provided by this routine
  329. //
  330. *lpcbTotalBytes = (DWORD) 0;
  331. *lpNumObjectTypes = (DWORD) 0;
  332. return( ERROR_SUCCESS );
  333. }
  334. }
  335. //
  336. // Check whether there is enough space allocated in the lppData
  337. //
  338. ULONG ulSpaceNeeded = CIISAPIDataDefinition.CIISAPIObjectType.TotalByteLength;
  339. if ( *lpcbTotalBytes < (DWORD) ulSpaceNeeded )
  340. {
  341. *lpcbTotalBytes = (DWORD) 0;
  342. *lpNumObjectTypes = (DWORD) 0;
  343. return( ERROR_MORE_DATA );
  344. }
  345. //
  346. // Copy the Data Definition to the buffer first
  347. //
  348. CI_ISAPI_DATA_DEFINITION * pCIISAPIDataDefinition =
  349. (CI_ISAPI_DATA_DEFINITION *) *lppData;
  350. RtlCopyMemory( pCIISAPIDataDefinition,
  351. &CIISAPIDataDefinition,
  352. sizeof(CI_ISAPI_DATA_DEFINITION) );
  353. DWORD * pdwCounter = (DWORD *)( pCIISAPIDataDefinition + 1 );
  354. //
  355. // Number of Object are always 1
  356. //
  357. *lpNumObjectTypes = 1;
  358. //
  359. // Fill in counter block.
  360. //
  361. *pdwCounter = CI_ISAPI_SIZE_OF_COUNTER_BLOCK;
  362. pdwCounter++;
  363. RtlCopyMemory( pdwCounter, TheMem.GetPointer(), CI_ISAPI_SIZE_OF_COUNTER_BLOCK - sizeof(DWORD) );
  364. //
  365. // Fill in the number of bytes copied including object and counter
  366. // definition and counter data
  367. //
  368. *lpcbTotalBytes = ulSpaceNeeded;
  369. *lppData = (void *) (((BYTE *) *lppData) + ulSpaceNeeded);
  370. return ERROR_SUCCESS;
  371. } //CollectCIISAPIPerformanceData
  372. //+---------------------------------------------------------------------------
  373. //
  374. // Function : DoneCIISAPIPerformanceData
  375. //
  376. // Purpose : dummy function
  377. //
  378. // Argument : none
  379. //
  380. // History : 23-March-94 t-joshh Created
  381. //
  382. //----------------------------------------------------------------------------
  383. DWORD DoneCIISAPIPerformanceData ( void )
  384. {
  385. return ERROR_SUCCESS;
  386. }