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.

359 lines
11 KiB

  1. Extensible Counter Loading & Unloading Utilities
  2. Design Specification and Overview
  3. created: 15 Feb 93
  4. a-robw
  5. russbl
  6. updated: 16 Nov 95
  7. a-robw
  8. Overview
  9. Device driver, service and application developers that wish to provide
  10. performance measuring capability in their software must have a way to
  11. incorporate the names of the performance counters and counter objects
  12. into the registry. Currently the only methods available are the manual
  13. installation of the names into the registry or for each developer to
  14. devise a scheme to do it programmatically. Since the "correct" way to
  15. do this is poorly documented and difficult to explain, the following
  16. utilities and library functions are provided to make the installation
  17. and removal of these extensible counters much simpler and less prone
  18. to error and confusion.
  19. The two command line utilities provided with Windows NT are shown below.
  20. > LodCtr MyDriver.INI
  21. > UnLodCtr MyDriver
  22. LoadPerf.DLL is provided to the software developer to provide access
  23. to these same functions (in both Unicode & ANSI formats) from within
  24. a setup program.
  25. LoadPerfCounterTextStrings (
  26. LPTSTR szCommandLine
  27. BOOL bQuietModeFlag)
  28. UnloadPerfCounterTextStrings (
  29. LPTSTR szCommandLine,
  30. BOOL bQuietMode)
  31. The contents of the string arguments in the above functions are the
  32. same as those for the command line.
  33. The installation utility (LodCtr) accepts as an argument the name of
  34. the device or application's counter .INI file. The format of the .INI
  35. file is described in detail later in this document. This utility will
  36. enter the counter names and explain text stored in the .INI file into
  37. the corresponding data file and update the necessary keys and values
  38. for the extensible performance counter DLL.
  39. The removal utility UnLodCtr accepts as an argument, the name of the
  40. regsistry key which is to have its names removed from the data files.
  41. This key is the registry key that the application, service or device
  42. driver us using under the ...\Services key and has the Performance
  43. subkey.
  44. The extensible performance counter DLL must be written to look up
  45. the base values of the counter names and explain text during
  46. initialization for this to function properly.
  47. .INI file format
  48. The .ini file for the extensible performance counter will consist
  49. of keys and values in a format similar to that of a MS-Windows
  50. .INI file (e.g. WIN.INI) This will allow a format that is somewhat
  51. self-documenting as well as allow current Win32 utilities to process
  52. it and parse the data (e.g. GetPrivateProfileString). A single file
  53. was selected to minimize the development and maintenance overhead of
  54. adding or modifying counters and adding foreign language support.
  55. The contents of the .INI file are described below:
  56. Usage Notes:
  57. The following assumptions are made in the use of counter names and
  58. explain text and should be followed in order to insure predictable and
  59. reliable operation.
  60. - Index number ranges must not be overlapping between drivers
  61. The range of index numbers used by an extensible counter
  62. must fall between the first and last values (see below).
  63. (gaps are allowed within the range used). If LodCtr is used
  64. then this won't be a problem.
  65. - Names must be assigned to EVEN numbers and Explain text assigned
  66. to ODD numbers.
  67. If the convention is followed as shown in the examples below,
  68. where each item is given an offset of an even number starting
  69. from 0, then LodCtr will do the right thing and make this
  70. assignment automatically. For this to work, however, the offest
  71. values MUST ALWAYS BE EVEN NUMBERS.
  72. - Manual assignment of counter index values is not recommended.
  73. Failure to follow all the assumptions or manually modifying
  74. or "hard-coding" index values may result in counter name
  75. text corruption or erroneous display of names.
  76. - Symbol file format must conform to the following:
  77. #define NAME decimal_number
  78. The symbol file processor is pretty dumb and can read .H header
  79. files but will only understand lines that conform to the above
  80. format. (in line comments after the number are OK) see the
  81. example below for more information.
  82. // Begin .INI file format
  83. [info]
  84. drivername=<name of device found under the CurrentControlSet\Services key>
  85. symbolfile=<.h file containing symbolic offsets of counters>
  86. [languages] // one key (value optional) for each language supported in file
  87. 009=
  88. .
  89. .
  90. .
  91. .
  92. [text] // counter & explain text for customer-defined counters
  93. offset_langid_NAME=text
  94. offset_langid_HELP=text
  95. // offset must be a symbolic constant (from symbolfile)
  96. // offset value must be an even number (see code example for why)
  97. // NAME and HELP are literal text and identify counter names or
  98. // explain text
  99. // langid must be listed as a key under [languages]
  100. // text must be entered on a single line (though it can be a long one)
  101. // end .INI file format
  102. The .ini file must be loaded into the registry before the extensible
  103. performance counter DLL is initialized (e.g. during or immediately
  104. after the driver is loaded for the first time. Once the counter names
  105. are loaded, however, they will remain until they are removed or NT is
  106. reinstalled.
  107. Following is an example of how the various components of an extensible
  108. counter would incorporate the definitions of the .INI file and the use
  109. of the LodCtr and UnLodCtr utilities. This example has one object and
  110. two counters.
  111. // begin devdef.H file
  112. // legal constant definitions
  113. #define OBJECT_1 0
  114. #define DEVICE_COUNTER_1 2
  115. #define DEVICE_COUNTER_2 4
  116. // end devdef.H file
  117. // BEGIN: Object & Counter structure initialization file
  118. // defines static structures used to build the perf data that is
  119. // returned by the extensible counter routines
  120. #include "devdef.h"
  121. MY_DEVICE_CTR_DEFINITION MyDeviceCtrDefinition = {
  122. { sizeof(MY_DEVICE_CTR_DEFINITION) + SIZE_OF_CTR_DATA,
  123. sizeof(MY_DEVICE_CTR_DEFINITION),
  124. sizeof(PERF_OBJECT_TYPE),
  125. OBJECT_1,
  126. 0,
  127. OBJECT_1,
  128. 0,
  129. PERF_DETAIL_ADVANCED,
  130. (sizeof(MY_DEVICE_CTR_DEFINITION-sizeof(PERF_OBJECT_TYPE))/
  131. sizeof(PERF_COUNTER_DEFINITION),
  132. 1,
  133. 0,
  134. 0
  135. },
  136. { sizeof(PERF_COUNTER_DEFINITION),
  137. DEVICE_COUNTER_1,
  138. 0,
  139. DEVICE_COUNTER_1,
  140. 0,
  141. 0,
  142. PERF_DETAIL_ADVANCED,
  143. PERF_COUNTER_COUNTER,
  144. sizeof(DWORD),
  145. DEVICE_COUNTER_1_DATA_OFFSET
  146. },
  147. { sizeof(PERF_COUNTER_DEFINITION),
  148. DEVICE_COUNTER_2,
  149. 0,
  150. DEVICE_COUNTER_2,
  151. 0,
  152. 0,
  153. PERF_DETAIL_ADVANCED,
  154. PERF_COUNTER_COUNTER,
  155. sizeof(DWORD),
  156. DEVICE_COUNTER_2_DATA_OFFSET,
  157. }
  158. };
  159. // END: Object & Counter structure initialization file
  160. // begin .INI file example
  161. [info]
  162. drivername=DriverName
  163. symbolfile=devdef.h
  164. [languages]
  165. 009=English
  166. 00C=OtherLanguage
  167. [text]
  168. OBJECT_1_009_NAME=Device Name
  169. OBJECT_1_009_HELP=Displays performance statistics on Device Name
  170. OBJECT_1_00C_NAME=Device Name in other language
  171. OBJECT_1_00C_HELP=Displays performance of Device Name in other language
  172. DEVICE_COUNTER_1_009_NAME=Counter A
  173. DEVICE_COUNTER_1_009_HELP=Displays the current value of Counter A
  174. DEVICE_COUNTER_1_00C_NAME=Counter A in other language
  175. DEVICE_COUNTER_1_00C_HELP=Displays the value of Counter A in other language
  176. DEVICE_COUNTER_2_009_NAME=Counter B
  177. DEVICE_COUNTER_2_009_HELP=Displays the current rate of Devices B
  178. DEVICE_COUNTER_2_00C_NAME=Counter B in other language
  179. DEVICE_COUNTER_2_00C_HELP=Displays the rate of Device B in other language
  180. // end .INI file
  181. OpenPerformanceData ( ... args ... )
  182. {
  183. .
  184. .
  185. .
  186. // execute this code before accessing or passing any perf. data
  187. // objects.
  188. status = RegOpenKeyEx (
  189. HKEY_LOCAL_MACHINE,
  190. "\\System\\CurrentControlSet\\Service\\DriverName\\Performance",
  191. NULL,
  192. SAM,
  193. &hKeyDriverPerf);
  194. size = sizeof (DWORD);
  195. Status = RegQueryValueEx (
  196. hKeyDriverPerf,
  197. "First Counter"
  198. 0L,
  199. &type,
  200. (LPBYTE)&dwFirstCounter,
  201. &size);
  202. size = sizeof (DWORD);
  203. Status = RegQueryValueEx(
  204. hKeyDriverPerf,
  205. "First Help"
  206. 0L,
  207. &type,
  208. (LPBYTE)&dwFirstHelp,
  209. &size);
  210. //
  211. // NOTE: the initialization program could also retrieve
  212. // LastCounter and LastHelp if they wanted to do
  213. // bounds checking on the new number. e.g.
  214. //
  215. // counter->CounterNameTitleIndex += dwFirstCounter;
  216. // if (counter->CounterNameTitleIndex > dwLastCounter) {
  217. // LogErrorToEventLog (INDEX_OUT_OF_BOUNDS);
  218. // }
  219. For each counter object {
  220. Object->ObjectNameTitleIndex += dwFirstCounter;
  221. Object->ObjectHelpTitleIndex += dwFirstHelp;
  222. for each counter definition in the object {
  223. counter->CounterNameTitleIndex += dwFirstCounter;
  224. counter->CounterHelpTitleIndex += dwFirstHelp;
  225. }
  226. }
  227. RegCloseKey (hKeyDriverPerf);
  228. .
  229. .
  230. .
  231. }
  232. When LodCtr has loaded the contents of the .INI file the following
  233. registry keys will have been updated. The ":" indicates a Value of
  234. a Key; other symbols are keys in the registry.
  235. MACHINE
  236. SYSTEM
  237. CurrentControlSet
  238. Services
  239. <devicename>
  240. Performance
  241. :First Counter (updated to show current value)
  242. :First Help (updated to show current value)
  243. :Last Counter (updated to show current value)
  244. :Last Help (updated to show current value)
  245. MACHINE
  246. SOFTWARE
  247. Microsoft
  248. Windows NT
  249. CurrentVersion
  250. Perflib
  251. :Last Counter (updated to show current value)
  252. :Last Help (updated to show current value)
  253. After UnLodCtr is run to remove a driver's counters from the data file,
  254. the following changes to the registry will take place
  255. MACHINE
  256. SYSTEM
  257. CurrentControlSet
  258. Services
  259. <devicename>
  260. Performance
  261. :First Counter (value deleted)
  262. :First Help (value deleted)
  263. :Last Counter (value deleted)
  264. :Last Help (value deleted)
  265. MACHINE
  266. SOFTWARE
  267. Microsoft
  268. Windows NT
  269. CurrentVersion
  270. Perflib
  271. :Last Counter (updated to show current value)
  272. :Last Help (updated to show current value)
  273.