nsldapctrutil.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. /*
  42. nsctrutil.c
  43. Performance Monitor utility functions
  44. This file implements the utility routines used to construct the
  45. common parts of a PERF_INSTANCE_DEFINITION (see winperf.h) and
  46. perform event logging functions.
  47. */
  48. #include <windows.h>
  49. #include <string.h>
  50. #include <winperf.h>
  51. #include "nsldapctrmc.h"
  52. #include "nsldapctrmsg.h"
  53. #include "nsldapctrutil.h"
  54. #define INITIAL_SIZE 1024L
  55. #define EXTEND_SIZE 1024L
  56. //
  57. // Global data definitions.
  58. //
  59. ULONG ulInfoBufferSize = 0;
  60. HANDLE hEventLog; // handle to event log
  61. DWORD dwLogUsers = 0; // count of functions using event log
  62. DWORD MESSAGE_LEVEL = 0;
  63. WCHAR GLOBAL_STRING[] = L"Global";
  64. WCHAR FOREIGN_STRING[] = L"Foreign";
  65. WCHAR COSTLY_STRING[] = L"Costly";
  66. WCHAR NULL_STRING[] = L"\0"; // pointer to null string
  67. // test for delimiter, end of line and non-digit characters
  68. // used by IsNumberInUnicodeList routine
  69. //
  70. #define DIGIT 1
  71. #define DELIMITER 2
  72. #define INVALID 3
  73. #define EvalThisChar(c,d) ( \
  74. (c == d) ? DELIMITER : \
  75. (c == 0) ? DELIMITER : \
  76. (c < (WCHAR)'0') ? INVALID : \
  77. (c > (WCHAR)'9') ? INVALID : \
  78. DIGIT)
  79. HANDLE
  80. MonOpenEventLog (
  81. )
  82. /*++
  83. Routine Description:
  84. Reads the level of event logging from the registry and opens the
  85. channel to the event logger for subsequent event log entries.
  86. Arguments:
  87. None
  88. Return Value:
  89. Handle to the event log for reporting events.
  90. NULL if open not successful.
  91. --*/
  92. {
  93. HKEY hAppKey;
  94. TCHAR LogLevelKeyName[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib";
  95. TCHAR LogLevelValueName[] = "EventLogLevel";
  96. LONG lStatus;
  97. DWORD dwLogLevel;
  98. DWORD dwValueType;
  99. DWORD dwValueSize;
  100. // if global value of the logging level not initialized or is disabled,
  101. // check the registry to see if it should be updated.
  102. if (!MESSAGE_LEVEL) {
  103. lStatus = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
  104. LogLevelKeyName,
  105. 0,
  106. KEY_READ,
  107. &hAppKey);
  108. dwValueSize = sizeof (dwLogLevel);
  109. if (lStatus == ERROR_SUCCESS) {
  110. lStatus = RegQueryValueEx (hAppKey,
  111. LogLevelValueName,
  112. (LPDWORD)NULL,
  113. &dwValueType,
  114. (LPBYTE)&dwLogLevel,
  115. &dwValueSize);
  116. if (lStatus == ERROR_SUCCESS) {
  117. MESSAGE_LEVEL = dwLogLevel;
  118. } else {
  119. MESSAGE_LEVEL = MESSAGE_LEVEL_DEFAULT;
  120. }
  121. RegCloseKey (hAppKey);
  122. } else {
  123. MESSAGE_LEVEL = MESSAGE_LEVEL_DEFAULT;
  124. }
  125. }
  126. if (hEventLog == NULL){
  127. hEventLog = RegisterEventSource (
  128. (LPTSTR)NULL, // Use Local Machine
  129. APP_NAME); // event log app name to find in registry
  130. }
  131. if (hEventLog != NULL) {
  132. dwLogUsers++; // increment count of perfctr log users
  133. }
  134. return (hEventLog);
  135. }
  136. VOID
  137. MonCloseEventLog (
  138. )
  139. /*++
  140. Routine Description:
  141. Closes the handle to the event logger if this is the last caller
  142. Arguments:
  143. None
  144. Return Value:
  145. None
  146. --*/
  147. {
  148. if (hEventLog != NULL) {
  149. dwLogUsers--; // decrement usage
  150. if (dwLogUsers <= 0) { // and if we're the last, then close up log
  151. DeregisterEventSource (hEventLog);
  152. }
  153. }
  154. }
  155. DWORD
  156. GetQueryType (
  157. IN LPWSTR lpValue
  158. )
  159. /*++
  160. GetQueryType
  161. returns the type of query described in the lpValue string so that
  162. the appropriate processing method may be used
  163. Arguments
  164. IN lpValue
  165. string passed to PerfRegQuery Value for processing
  166. Return Value
  167. QUERY_GLOBAL
  168. if lpValue == 0 (null pointer)
  169. lpValue == pointer to Null string
  170. lpValue == pointer to "Global" string
  171. QUERY_FOREIGN
  172. if lpValue == pointer to "Foreign" string
  173. QUERY_COSTLY
  174. if lpValue == pointer to "Costly" string
  175. otherwise:
  176. QUERY_ITEMS
  177. --*/
  178. {
  179. WCHAR *pwcArgChar, *pwcTypeChar;
  180. BOOL bFound;
  181. if (lpValue == 0) {
  182. return QUERY_GLOBAL;
  183. } else if (*lpValue == 0) {
  184. return QUERY_GLOBAL;
  185. }
  186. // check for "Global" request
  187. pwcArgChar = lpValue;
  188. pwcTypeChar = GLOBAL_STRING;
  189. bFound = TRUE; // assume found until contradicted
  190. // check to the length of the shortest string
  191. while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
  192. if (*pwcArgChar++ != *pwcTypeChar++) {
  193. bFound = FALSE; // no match
  194. break; // bail out now
  195. }
  196. }
  197. if (bFound) return QUERY_GLOBAL;
  198. // check for "Foreign" request
  199. pwcArgChar = lpValue;
  200. pwcTypeChar = FOREIGN_STRING;
  201. bFound = TRUE; // assume found until contradicted
  202. // check to the length of the shortest string
  203. while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
  204. if (*pwcArgChar++ != *pwcTypeChar++) {
  205. bFound = FALSE; // no match
  206. break; // bail out now
  207. }
  208. }
  209. if (bFound) return QUERY_FOREIGN;
  210. // check for "Costly" request
  211. pwcArgChar = lpValue;
  212. pwcTypeChar = COSTLY_STRING;
  213. bFound = TRUE; // assume found until contradicted
  214. // check to the length of the shortest string
  215. while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
  216. if (*pwcArgChar++ != *pwcTypeChar++) {
  217. bFound = FALSE; // no match
  218. break; // bail out now
  219. }
  220. }
  221. if (bFound) return QUERY_COSTLY;
  222. // if not Global and not Foreign and not Costly,
  223. // then it must be an item list
  224. return QUERY_ITEMS;
  225. }
  226. BOOL
  227. IsNumberInUnicodeList (
  228. IN DWORD dwNumber,
  229. IN LPWSTR lpwszUnicodeList
  230. )
  231. /*++
  232. IsNumberInUnicodeList
  233. Arguments:
  234. IN dwNumber
  235. DWORD number to find in list
  236. IN lpwszUnicodeList
  237. Null terminated, Space delimited list of decimal numbers
  238. Return Value:
  239. TRUE:
  240. dwNumber was found in the list of unicode number strings
  241. FALSE:
  242. dwNumber was not found in the list.
  243. --*/
  244. {
  245. DWORD dwThisNumber;
  246. WCHAR *pwcThisChar;
  247. BOOL bValidNumber;
  248. BOOL bNewItem;
  249. //BOOL bReturnValue;
  250. WCHAR wcDelimiter; // could be an argument to be more flexible
  251. if (lpwszUnicodeList == 0) return FALSE; // null pointer, # not found
  252. pwcThisChar = lpwszUnicodeList;
  253. dwThisNumber = 0;
  254. wcDelimiter = (WCHAR)' ';
  255. bValidNumber = FALSE;
  256. bNewItem = TRUE;
  257. while (TRUE) {
  258. switch (EvalThisChar (*pwcThisChar, wcDelimiter)) {
  259. case DIGIT:
  260. // if this is the first digit after a delimiter, then
  261. // set flags to start computing the new number
  262. if (bNewItem) {
  263. bNewItem = FALSE;
  264. bValidNumber = TRUE;
  265. }
  266. if (bValidNumber) {
  267. dwThisNumber *= 10;
  268. dwThisNumber += (*pwcThisChar - (WCHAR)'0');
  269. }
  270. break;
  271. case DELIMITER:
  272. // a delimiter is either the delimiter character or the
  273. // end of the string ('\0') if when the delimiter has been
  274. // reached a valid number was found, then compare it to the
  275. // number from the argument list. if this is the end of the
  276. // string and no match was found, then return.
  277. //
  278. if (bValidNumber) {
  279. if (dwThisNumber == dwNumber) return TRUE;
  280. bValidNumber = FALSE;
  281. }
  282. if (*pwcThisChar == 0) {
  283. return FALSE;
  284. } else {
  285. bNewItem = TRUE;
  286. dwThisNumber = 0;
  287. }
  288. break;
  289. case INVALID:
  290. // if an invalid character was encountered, ignore all
  291. // characters up to the next delimiter and then start fresh.
  292. // the invalid number is not compared.
  293. bValidNumber = FALSE;
  294. break;
  295. default:
  296. break;
  297. }
  298. pwcThisChar++;
  299. }
  300. } // IsNumberInUnicodeList