summaryrefslogtreecommitdiffstats
path: root/ldap/servers/slapd/ntperfdll/nsldapctrutil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ldap/servers/slapd/ntperfdll/nsldapctrutil.cpp')
-rw-r--r--ldap/servers/slapd/ntperfdll/nsldapctrutil.cpp364
1 files changed, 364 insertions, 0 deletions
diff --git a/ldap/servers/slapd/ntperfdll/nsldapctrutil.cpp b/ldap/servers/slapd/ntperfdll/nsldapctrutil.cpp
new file mode 100644
index 00000000..1783aee2
--- /dev/null
+++ b/ldap/servers/slapd/ntperfdll/nsldapctrutil.cpp
@@ -0,0 +1,364 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/*
+
+ nsctrutil.c
+
+ Performance Monitor utility functions
+
+ This file implements the utility routines used to construct the
+ common parts of a PERF_INSTANCE_DEFINITION (see winperf.h) and
+ perform event logging functions.
+
+ */
+
+#include <windows.h>
+#include <string.h>
+#include <winperf.h>
+#include "nsldapctrmc.h"
+#include "nsldapctrmsg.h"
+#include "nsldapctrutil.h"
+
+#define INITIAL_SIZE 1024L
+#define EXTEND_SIZE 1024L
+
+//
+// Global data definitions.
+//
+
+ULONG ulInfoBufferSize = 0;
+
+HANDLE hEventLog; // handle to event log
+
+DWORD dwLogUsers = 0; // count of functions using event log
+
+DWORD MESSAGE_LEVEL = 0;
+
+WCHAR GLOBAL_STRING[] = L"Global";
+WCHAR FOREIGN_STRING[] = L"Foreign";
+WCHAR COSTLY_STRING[] = L"Costly";
+
+WCHAR NULL_STRING[] = L"\0"; // pointer to null string
+
+// test for delimiter, end of line and non-digit characters
+// used by IsNumberInUnicodeList routine
+//
+#define DIGIT 1
+#define DELIMITER 2
+#define INVALID 3
+
+#define EvalThisChar(c,d) ( \
+ (c == d) ? DELIMITER : \
+ (c == 0) ? DELIMITER : \
+ (c < (WCHAR)'0') ? INVALID : \
+ (c > (WCHAR)'9') ? INVALID : \
+ DIGIT)
+
+HANDLE
+MonOpenEventLog (
+)
+/*++
+
+Routine Description:
+
+ Reads the level of event logging from the registry and opens the
+ channel to the event logger for subsequent event log entries.
+
+Arguments:
+
+ None
+
+Return Value:
+
+ Handle to the event log for reporting events.
+ NULL if open not successful.
+
+--*/
+
+
+{
+
+
+ HKEY hAppKey;
+
+
+ TCHAR LogLevelKeyName[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib";
+
+
+ TCHAR LogLevelValueName[] = "EventLogLevel";
+
+ LONG lStatus;
+
+ DWORD dwLogLevel;
+ DWORD dwValueType;
+ DWORD dwValueSize;
+
+ // if global value of the logging level not initialized or is disabled,
+ // check the registry to see if it should be updated.
+
+ if (!MESSAGE_LEVEL) {
+
+ lStatus = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
+ LogLevelKeyName,
+ 0,
+ KEY_READ,
+ &hAppKey);
+
+ dwValueSize = sizeof (dwLogLevel);
+
+ if (lStatus == ERROR_SUCCESS) {
+ lStatus = RegQueryValueEx (hAppKey,
+ LogLevelValueName,
+ (LPDWORD)NULL,
+ &dwValueType,
+ (LPBYTE)&dwLogLevel,
+ &dwValueSize);
+
+ if (lStatus == ERROR_SUCCESS) {
+ MESSAGE_LEVEL = dwLogLevel;
+ } else {
+ MESSAGE_LEVEL = MESSAGE_LEVEL_DEFAULT;
+ }
+ RegCloseKey (hAppKey);
+ } else {
+
+
+ MESSAGE_LEVEL = MESSAGE_LEVEL_DEFAULT;
+ }
+ }
+
+ if (hEventLog == NULL){
+ hEventLog = RegisterEventSource (
+ (LPTSTR)NULL, // Use Local Machine
+ APP_NAME); // event log app name to find in registry
+ }
+
+ if (hEventLog != NULL) {
+ dwLogUsers++; // increment count of perfctr log users
+ }
+ return (hEventLog);
+}
+
+VOID
+MonCloseEventLog (
+)
+/*++
+
+Routine Description:
+
+ Closes the handle to the event logger if this is the last caller
+
+Arguments:
+
+ None
+
+Return Value:
+
+ None
+
+--*/
+{
+ if (hEventLog != NULL) {
+ dwLogUsers--; // decrement usage
+ if (dwLogUsers <= 0) { // and if we're the last, then close up log
+ DeregisterEventSource (hEventLog);
+ }
+ }
+}
+
+DWORD
+GetQueryType (
+ IN LPWSTR lpValue
+)
+/*++
+
+GetQueryType
+
+ returns the type of query described in the lpValue string so that
+ the appropriate processing method may be used
+
+Arguments
+
+ IN lpValue
+ string passed to PerfRegQuery Value for processing
+
+Return Value
+
+ QUERY_GLOBAL
+ if lpValue == 0 (null pointer)
+ lpValue == pointer to Null string
+ lpValue == pointer to "Global" string
+
+ QUERY_FOREIGN
+ if lpValue == pointer to "Foreign" string
+
+ QUERY_COSTLY
+ if lpValue == pointer to "Costly" string
+
+ otherwise:
+
+ QUERY_ITEMS
+
+--*/
+{
+ WCHAR *pwcArgChar, *pwcTypeChar;
+ BOOL bFound;
+
+ if (lpValue == 0) {
+ return QUERY_GLOBAL;
+ } else if (*lpValue == 0) {
+ return QUERY_GLOBAL;
+ }
+
+ // check for "Global" request
+
+ pwcArgChar = lpValue;
+ pwcTypeChar = GLOBAL_STRING;
+ bFound = TRUE; // assume found until contradicted
+
+ // check to the length of the shortest string
+
+ while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
+ if (*pwcArgChar++ != *pwcTypeChar++) {
+ bFound = FALSE; // no match
+ break; // bail out now
+ }
+ }
+
+ if (bFound) return QUERY_GLOBAL;
+
+ // check for "Foreign" request
+
+ pwcArgChar = lpValue;
+ pwcTypeChar = FOREIGN_STRING;
+ bFound = TRUE; // assume found until contradicted
+
+ // check to the length of the shortest string
+
+ while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
+ if (*pwcArgChar++ != *pwcTypeChar++) {
+ bFound = FALSE; // no match
+ break; // bail out now
+ }
+ }
+
+ if (bFound) return QUERY_FOREIGN;
+
+ // check for "Costly" request
+
+ pwcArgChar = lpValue;
+ pwcTypeChar = COSTLY_STRING;
+ bFound = TRUE; // assume found until contradicted
+
+ // check to the length of the shortest string
+
+ while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
+ if (*pwcArgChar++ != *pwcTypeChar++) {
+ bFound = FALSE; // no match
+ break; // bail out now
+ }
+ }
+
+ if (bFound) return QUERY_COSTLY;
+
+ // if not Global and not Foreign and not Costly,
+ // then it must be an item list
+
+ return QUERY_ITEMS;
+
+}
+
+BOOL
+IsNumberInUnicodeList (
+ IN DWORD dwNumber,
+ IN LPWSTR lpwszUnicodeList
+)
+/*++
+
+IsNumberInUnicodeList
+
+Arguments:
+
+ IN dwNumber
+ DWORD number to find in list
+
+ IN lpwszUnicodeList
+ Null terminated, Space delimited list of decimal numbers
+
+Return Value:
+
+ TRUE:
+ dwNumber was found in the list of unicode number strings
+
+ FALSE:
+ dwNumber was not found in the list.
+
+--*/
+{
+ DWORD dwThisNumber;
+ WCHAR *pwcThisChar;
+ BOOL bValidNumber;
+ BOOL bNewItem;
+ //BOOL bReturnValue;
+ WCHAR wcDelimiter; // could be an argument to be more flexible
+
+ if (lpwszUnicodeList == 0) return FALSE; // null pointer, # not found
+
+ pwcThisChar = lpwszUnicodeList;
+ dwThisNumber = 0;
+ wcDelimiter = (WCHAR)' ';
+ bValidNumber = FALSE;
+ bNewItem = TRUE;
+
+ while (TRUE) {
+ switch (EvalThisChar (*pwcThisChar, wcDelimiter)) {
+ case DIGIT:
+ // if this is the first digit after a delimiter, then
+ // set flags to start computing the new number
+ if (bNewItem) {
+ bNewItem = FALSE;
+ bValidNumber = TRUE;
+ }
+ if (bValidNumber) {
+ dwThisNumber *= 10;
+ dwThisNumber += (*pwcThisChar - (WCHAR)'0');
+ }
+ break;
+
+ case DELIMITER:
+ // a delimiter is either the delimiter character or the
+ // end of the string ('\0') if when the delimiter has been
+ // reached a valid number was found, then compare it to the
+ // number from the argument list. if this is the end of the
+ // string and no match was found, then return.
+ //
+ if (bValidNumber) {
+ if (dwThisNumber == dwNumber) return TRUE;
+ bValidNumber = FALSE;
+ }
+ if (*pwcThisChar == 0) {
+ return FALSE;
+ } else {
+ bNewItem = TRUE;
+ dwThisNumber = 0;
+ }
+ break;
+
+ case INVALID:
+ // if an invalid character was encountered, ignore all
+ // characters up to the next delimiter and then start fresh.
+ // the invalid number is not compared.
+ bValidNumber = FALSE;
+ break;
+
+ default:
+ break;
+
+ }
+ pwcThisChar++;
+ }
+
+} // IsNumberInUnicodeList