summaryrefslogtreecommitdiffstats
path: root/ldap/servers/slapd/ntperfdll/nsldapctr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ldap/servers/slapd/ntperfdll/nsldapctr.cpp')
-rw-r--r--ldap/servers/slapd/ntperfdll/nsldapctr.cpp985
1 files changed, 985 insertions, 0 deletions
diff --git a/ldap/servers/slapd/ntperfdll/nsldapctr.cpp b/ldap/servers/slapd/ntperfdll/nsldapctr.cpp
new file mode 100644
index 00000000..21bf429d
--- /dev/null
+++ b/ldap/servers/slapd/ntperfdll/nsldapctr.cpp
@@ -0,0 +1,985 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/*
+ nsctr.c
+
+ Netscape server performance monitor hooks.
+
+
+ ***********************************************************************
+ HOW TO ADD A NEW PERFMON STATISTIC
+ 1. add to StatSlot or StatHeader struct
+ 2. add new counter definition to NS_DATA_DEFINITION in nsctrs.h
+ 3. define the offset of your new counter in nsctrdef.h
+ 4. add your counter initialization to NSDataDefinition in nsctr.cpp
+ 5. update CollectNSPerformanceData to collect your data
+ 6. modify nsctrs.ini to contain the text info for your counter
+ these are keyed off the "tag" you used in step 3
+ ***********************************************************************
+ HOW TO UPDATE THE REGISTRY
+ 1. run regini nsreg.ini
+ 2. run lodctr nsctrs.ini
+ ***********************************************************************
+ */
+
+#define UNICODE
+
+#include <windows.h>
+#include <string.h>
+#include <winperf.h>
+#include <stdio.h>
+#include <regstr.h>
+#include "nsldapctrs.h"
+#include "nsldapctrmsg.h"
+#include "nsldapctrutil.h"
+#include "nsldapctrmc.h"
+#include "nsldapctrdef.h"
+
+#include "nt/regparms.h"
+
+#include "../agtmmap.h"
+
+#define NUM_INSTANCES 0
+#define MAGT_MAX_LINELEN 255
+
+
+/* --- Constant Performance Counter Declaration --------------------------------------------*/
+
+NS_DATA_DEFINITION NSDataDefinition = {
+
+ { sizeof(NS_DATA_DEFINITION) + SIZE_OF_NS_PERFORMANCE_DATA,
+ sizeof(NS_DATA_DEFINITION),
+ sizeof(PERF_OBJECT_TYPE),
+ NS_OBJ,
+ 0,
+ NS_OBJ,
+ 0,
+ PERF_DETAIL_NOVICE,
+ (sizeof(NS_DATA_DEFINITION)-sizeof(PERF_OBJECT_TYPE))/
+ sizeof(PERF_COUNTER_DEFINITION),
+ 4L,
+ NUM_INSTANCES,
+ 0,
+ 0,
+ 0
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ CONN_RATE,
+ 0,
+ CONN_RATE,
+ 0,
+ 0,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_COUNTER,
+ sizeof(DWORD),
+ NUM_CONN_RATE_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ THROUGHPUT,
+ 0,
+ THROUGHPUT,
+ 0,
+ -3,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_COUNTER,
+ sizeof(DWORD),
+ NUM_THROUGHPUT_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ TOTAL_BYTES_WRITTEN,
+ 0,
+ TOTAL_BYTES_WRITTEN,
+ 0,
+ -3,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_RAWCOUNT,
+ sizeof(DWORD),
+ NUM_TOTAL_BYTES_WRITTEN_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ TOTAL_BYTES_READ,
+ 0,
+ TOTAL_BYTES_READ,
+ 0,
+ -3,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_RAWCOUNT,
+ sizeof(DWORD),
+ NUM_TOTAL_BYTES_READ_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ OP_RATE,
+ 0,
+ OP_RATE,
+ 0,
+ -1,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_COUNTER,
+ sizeof(DWORD),
+ NUM_OP_RATE_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ TOTAL_ERRORS,
+ 0,
+ TOTAL_ERRORS,
+ 0,
+ 0,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_RAWCOUNT,
+ sizeof(DWORD),
+ NUM_TOTAL_ERRORS_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ SEARCH_RATE,
+ 0,
+ SEARCH_RATE,
+ 0,
+ -1,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_COUNTER,
+ sizeof(DWORD),
+ NUM_SEARCH_RATE_OFFSET
+ } ,
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ ADD_RATE,
+ 0,
+ ADD_RATE,
+ 0,
+ 0,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_COUNTER,
+ sizeof(DWORD),
+ ADD_RATE_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ DELETE_RATE,
+ 0,
+ DELETE_RATE,
+ 0,
+ 0,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_COUNTER,
+ sizeof(DWORD),
+ DELETE_RATE_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ MODIFY_RATE,
+ 0,
+ MODIFY_RATE,
+ 0,
+ 0,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_COUNTER,
+ sizeof(DWORD),
+ MODIFY_RATE_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ COMPARE_RATE,
+ 0,
+ COMPARE_RATE,
+ 0,
+ -1,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_COUNTER,
+ sizeof(DWORD),
+ COMPARE_RATE_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ MODDN_RATE,
+ 0,
+ MODDN_RATE,
+ 0,
+ 0,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_COUNTER,
+ sizeof(DWORD),
+ MODDN_RATE_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ CONNECTIONS,
+ 0,
+ CONNECTIONS,
+ 0,
+ 0,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_RAWCOUNT,
+ sizeof(DWORD),
+ CONNECTIONS_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ BIND_RATE,
+ 0,
+ BIND_RATE,
+ 0,
+ -1,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_COUNTER,
+ sizeof(DWORD),
+ BIND_RATE_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ ENTRIES_RETURNED,
+ 0,
+ ENTRIES_RETURNED,
+ 0,
+ 0,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_RAWCOUNT,
+ sizeof(DWORD),
+ ENTRIES_RETURNED_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ ENTRIES_RETURNED_RATE,
+ 0,
+ ENTRIES_RETURNED_RATE,
+ 0,
+ -1,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_COUNTER,
+ sizeof(DWORD),
+ ENTRIES_RETURNED_RATE_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ REFERRALS_RETURNED,
+ 0,
+ REFERRALS_RETURNED,
+ 0,
+ 0,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_RAWCOUNT,
+ sizeof(DWORD),
+ REFERRALS_RETURNED_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ REFERRALS_RETURNED_RATE,
+ 0,
+ REFERRALS_RETURNED_RATE,
+ 0,
+ -1,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_COUNTER,
+ sizeof(DWORD),
+ REFERRALS_RETURNED_RATE_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ BYTES_READ_RATE,
+ 0,
+ BYTES_READ_RATE,
+ 0,
+ -3,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_COUNTER,
+ sizeof(DWORD),
+ BYTES_READ_RATE_OFFSET
+ },
+ {
+ sizeof(PERF_COUNTER_DEFINITION),
+ BYTES_WRITTEN_RATE,
+ 0,
+ BYTES_WRITTEN_RATE,
+ 0,
+ -3,
+ PERF_DETAIL_NOVICE,
+ PERF_COUNTER_COUNTER,
+ sizeof(DWORD),
+ BYTES_WRITTEN_RATE_OFFSET
+ }
+
+
+};
+
+/* --- Data structs ----------------------------------------------------------------------- */
+typedef struct instance_list_t {
+ PERF_INSTANCE_DEFINITION instance;
+ PWSTR pInstanceName;
+ PWSTR pConfPath;
+ agt_stats_t * pData;
+ struct instance_list_t * pNext;
+} instance_list_t;
+
+
+/* --- Globals ---------------------------------------------------------------------------- */
+static BOOL bInitialized = FALSE;
+static DWORD dwOpenCount = 0; /* Count of threads holding DLL open */
+static DWORD dwInstanceCount = 0;
+static instance_list_t *pInstanceList = NULL;
+
+#define export extern "C"
+
+
+/*-------------------------------------------------------------------------
+ *
+ * MagtReadLine: Reads one line of text (up to n chars) from specified
+ * file.
+ *
+ * Returns: Len read - No error
+ * -1 - Errors
+ *
+ *-----------------------------------------------------------------------*/
+
+int MagtReadLine(char *buf, int n, FILE *fp)
+{
+ if (fgets(buf, n, fp) != NULL)
+ {
+ return(strlen(buf));
+ }
+ else
+ {
+ return(-1);
+ }
+}
+
+
+
+/* --- strips quotes off of a quoted string -------------------------------------- */
+
+
+char *dequote(char *quoted_string)
+{
+ char *return_string = (char *)malloc((strlen(quoted_string) - 2) * sizeof(char) );
+ char *pQuo = quoted_string;
+ char *pRet = return_string;
+
+ for(; *pQuo; pQuo++) {
+ if (*pQuo != '\"')
+ *(pRet++) = *pQuo;
+ }
+ *pRet = '\0';
+
+ return return_string;
+
+}
+
+/* --- gets the instance dir from conf file ------------------------------------- */
+
+
+/*
+ * The body of this function is pretty much copied from
+ * ldapserver/ldap/servers/snmp/ntagt/nsldapagt_nt.c
+ *
+ */
+char *getRootDirFromConfFile(PWSTR confpath)
+{
+ char *rootDir = NULL;
+ const char *config = "\\config\0" ;
+ char instanceDir[MAGT_MAX_LINELEN + 1] = "";
+ size_t len ;
+ char filename[256];
+
+ if (confpath) {
+ sprintf(filename, "%S", confpath);
+ len = strlen(filename) - strlen(config) ;
+ strncpy(instanceDir, filename, len);
+ rootDir = _strdup(instanceDir) ; // allocate memory for rootDir and set up to value pointed by instanceDir
+ return rootDir ;
+ }
+ else return NULL ;
+}
+
+static DWORD MapSharedMem(char* path, agt_stats_t **ptr)
+{
+ HANDLE hFile = NULL;
+ HANDLE hMapFile = NULL;
+ LPVOID memory = NULL;
+
+ *ptr = NULL;
+ /* Open existing disk file for read */
+ hFile = CreateFileA(path,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if ( hFile == INVALID_HANDLE_VALUE || hFile == NULL ) return GetLastError();
+
+ /* Create mapped file handle for reading */
+ hMapFile = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0,
+ sizeof(struct agt_stats_t),
+ NULL);
+ if ( hMapFile == NULL ) {
+ CloseHandle( hFile );
+ return GetLastError();
+ }
+
+ /* Create addr ptr to the start of the file */
+ memory = MapViewOfFileEx( hMapFile, FILE_MAP_READ, 0, 0,
+ sizeof(struct agt_stats_t), NULL );
+ CloseHandle( hMapFile );
+ CloseHandle( hFile );
+ if ( memory == NULL ) {
+ return GetLastError();
+ }
+ *ptr = (agt_stats_t *)memory;
+ return 0;
+}
+
+static DWORD UnmapSharedMem(agt_stats_t **ptr)
+{
+ return UnmapViewOfFile( (LPVOID)*ptr) ? 0 : -1;
+}
+
+/* --- Open Function --------------------------------------------------------------------- */
+
+
+/* _FindNetscapeServers()
+ * Function to loop through registry looking for netscape servers
+ * Stores them into pInstanceList as it finds them.
+ */
+
+#define MAX_KEY_SIZE 128
+DWORD
+_FindNetscapeServers()
+{
+ LONG regStatus,
+ status;
+ HKEY hKeyNetscape = NULL,
+ hKeyNetscapeConf;
+ DWORD dwKey,
+ type,
+ dwServerKeySize,
+ size,
+ dwServerCount = 0;
+ WCHAR szServerKeyName[MAX_KEY_SIZE],
+ szConfKeyName[MAX_KEY_SIZE + sizeof(KEY_SOFTWARE_NETSCAPE)],
+ szPath[MAX_KEY_SIZE];
+ FILETIME fileTime;
+ instance_list_t *pNew;
+ DWORD iUniqueID = 0;
+
+ regStatus = RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE,
+ TEXT(KEY_SOFTWARE_NETSCAPE) TEXT("\\") TEXT(DS_KEY_ROOT),
+ 0L,
+ KEY_ALL_ACCESS,
+ &hKeyNetscape);
+
+ if (regStatus != ERROR_SUCCESS) {
+ goto ExitPoint;
+ }
+
+ dwKey = 0;
+ do {
+ dwServerKeySize = MAX_KEY_SIZE;
+ regStatus = RegEnumKeyEx(
+ hKeyNetscape,
+ dwKey,
+ szServerKeyName,
+ &dwServerKeySize,
+ NULL,
+ 0,
+ 0,
+ &fileTime);
+ dwKey++;
+
+ if (regStatus == ERROR_SUCCESS) {
+
+ regStatus = RegOpenKeyEx(
+ hKeyNetscape,
+ szServerKeyName,
+ 0L,
+ KEY_ALL_ACCESS,
+ &hKeyNetscapeConf);
+
+ if (regStatus != ERROR_SUCCESS) {
+ continue;
+ }
+
+ /* Now look for "ConfigurationPath" to find 3.0 netscape servers */
+ size = MAX_KEY_SIZE;
+ status = RegQueryValueEx(
+ hKeyNetscapeConf,
+ TEXT(VALUE_CONFIG_PATH),
+ 0L,
+ &type,
+ (LPBYTE)szPath,
+ &size);
+ if ( status == ERROR_SUCCESS ) {
+ /* this is a netscape server */
+ if ( (pNew = (instance_list_t *)malloc(sizeof(instance_list_t))) == NULL) {
+ status = (unsigned long)-1;
+ RegCloseKey(hKeyNetscapeConf);
+ goto ExitPoint;
+ }
+ if ( (pNew->pInstanceName = (PWCH)malloc(sizeof(WCHAR) *(dwServerKeySize+1))) == NULL) {
+ status = (unsigned long)-1;
+ RegCloseKey(hKeyNetscapeConf);
+ goto ExitPoint;
+ }
+
+ if ( (pNew->pConfPath = (PWCH)malloc(sizeof(WCHAR) *(size+1))) == NULL) {
+ status = (unsigned long)-1;
+ RegCloseKey(hKeyNetscapeConf);
+ goto ExitPoint;
+ }
+
+
+ pNew->pData = NULL;
+
+ pNew->instance.ParentObjectTitleIndex = 0;
+ pNew->instance.ParentObjectInstance = 0;
+ pNew->instance.UniqueID = -1;
+ pNew->instance.NameOffset = sizeof(PERF_INSTANCE_DEFINITION);
+ lstrcpy(pNew->pInstanceName, szServerKeyName);
+ lstrcpy(pNew->pConfPath, szPath);
+
+ pNew->instance.NameLength = (dwServerKeySize+1) * sizeof(WCHAR);
+ pNew->instance.ByteLength = sizeof(PERF_INSTANCE_DEFINITION) +
+ (((pNew->instance.NameLength + sizeof(DWORD)-1)/sizeof(DWORD))*sizeof(DWORD));
+ pNew->instance.UniqueID = iUniqueID++;
+
+ pNew->pNext = pInstanceList;
+ pInstanceList = pNew;
+
+ dwServerCount++;
+ }
+
+ RegCloseKey(hKeyNetscapeConf);
+ }
+
+ } while ( regStatus != ERROR_NO_MORE_ITEMS );
+
+ExitPoint:
+ if (hKeyNetscape)
+ RegCloseKey (hKeyNetscape);
+
+ return dwServerCount;
+}
+
+/* _OpenNetscapeServers()
+ * Once the pInstanceList has been created, this routine will open the instances
+ * of the netscape servers;
+ */
+#define MAX_FILE_LEN 128
+DWORD
+_OpenNetscapeServers()
+{
+ LONG status;
+ DWORD dwServerCount = 0;
+ instance_list_t *pInstance;
+ char *szRootDir;
+ char tmpstatsfile[MAX_FILE_LEN];
+ int err;
+
+ for (pInstance = pInstanceList; pInstance; pInstance = pInstance->pNext) {
+
+ /* open the memory map */
+
+ /*
+ * Get directory for our stats file
+ */
+
+ szRootDir = getRootDirFromConfFile(pInstance->pConfPath);
+ if( szRootDir == NULL){
+ status = GetLastError();
+ continue ;
+ }
+ wsprintfA(tmpstatsfile, "%s/logs/%s", szRootDir, AGT_STATS_FILE);
+ err = MapSharedMem(tmpstatsfile,&pInstance->pData);
+ if ( 0 != err ) {
+ REPORT_ERROR (NSPERF_UNABLE_MAP_VIEW_OF_FILE, LOG_USER);
+ status = GetLastError(); // return error
+ continue;
+ } else {
+ dwServerCount++;
+ }
+
+ if(szRootDir != NULL){
+ free(szRootDir);
+ }
+
+ }
+
+ return dwServerCount;
+}
+
+export DWORD APIENTRY
+OpenNSPerformanceData(LPWSTR lpDeviceNames)
+{
+ LONG status;
+ TCHAR szMappedObject[] = TEXT(SVR_ID_SERVICE) TEXT("Statistics");
+ HKEY hKeyDriverPerf;
+ DWORD size;
+ DWORD type;
+ DWORD dwFirstCounter;
+ DWORD dwFirstHelp;
+
+ if (!dwOpenCount) {
+
+ hEventLog = MonOpenEventLog();
+
+
+ if ( !_FindNetscapeServers() ) {
+ /* No netscape servers found */
+ status = (unsigned long)-1;
+ goto OpenExitPoint;
+ }
+
+ if ( !(dwInstanceCount = _OpenNetscapeServers()) ) {
+ /* No netscape servers are active */
+ status = (unsigned long)-1;
+ goto OpenExitPoint;
+ }
+
+ /* Now load help keys from registry */
+
+ status = RegOpenKeyEx (
+ HKEY_LOCAL_MACHINE,
+ TEXT("System\\CurrentControlSet\\Services") TEXT("\\") TEXT(SVR_ID_SERVICE) TEXT(SVR_VERSION) TEXT("\\") TEXT(KEY_PERFORMANCE),
+ 0L,
+ KEY_ALL_ACCESS,
+ &hKeyDriverPerf);
+
+ if (status != ERROR_SUCCESS) {
+ REPORT_ERROR_DATA (NSPERF_UNABLE_OPEN_DRIVER_KEY, LOG_USER,
+ &status, sizeof(status));
+ goto OpenExitPoint;
+ }
+
+ size = sizeof (DWORD);
+ status = RegQueryValueEx(
+ hKeyDriverPerf,
+ TEXT("First Counter"),
+ 0L,
+ &type,
+ (LPBYTE)&dwFirstCounter,
+ &size);
+
+ if (status != ERROR_SUCCESS) {
+ REPORT_ERROR_DATA (NSPERF_UNABLE_READ_FIRST_COUNTER, LOG_USER,
+ &status, sizeof(status));
+ goto OpenExitPoint;
+ }
+
+ size = sizeof (DWORD);
+ status = RegQueryValueEx(
+ hKeyDriverPerf,
+ TEXT("First Help"),
+ 0L,
+ &type,
+ (LPBYTE)&dwFirstHelp,
+ &size);
+
+ if (status != ERROR_SUCCESS) {
+ REPORT_ERROR_DATA (NSPERF_UNABLE_READ_FIRST_HELP, LOG_USER,
+ &status, sizeof(status));
+ goto OpenExitPoint;
+ }
+
+ NSDataDefinition.NS_ObjectType.ObjectNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.NS_ObjectType.ObjectHelpTitleIndex += dwFirstHelp;
+
+ NSDataDefinition.connection_rate.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.connection_rate.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.throughput.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.throughput.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.total_bytes_written.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.total_bytes_written.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.total_bytes_read.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.total_bytes_read.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.operation_rate.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.operation_rate.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.total_errors.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.total_errors.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.search_rate.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.search_rate.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.add_rate.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.add_rate.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.delete_rate.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.delete_rate.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.modify_rate.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.modify_rate.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.compare_rate.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.compare_rate.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.moddn_rate.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.moddn_rate.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.connections.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.connections.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.bind_rate.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.bind_rate.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.entries_returned.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.entries_returned.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.entries_returned_rate.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.entries_returned_rate.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.referrals_returned.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.referrals_returned.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.referrals_returned_rate.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.referrals_returned_rate.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.bytes_read_rate.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.bytes_read_rate.CounterHelpTitleIndex += dwFirstHelp;
+ NSDataDefinition.bytes_written_rate.CounterNameTitleIndex += dwFirstCounter;
+ NSDataDefinition.bytes_written_rate.CounterHelpTitleIndex += dwFirstHelp;
+
+ RegCloseKey (hKeyDriverPerf);
+
+ bInitialized = TRUE;
+ }
+
+ dwOpenCount++;
+
+ status = ERROR_SUCCESS;
+
+OpenExitPoint:
+
+ return status;
+}
+
+/* --- Close Function -------------------------------------------------------------------- */
+export DWORD APIENTRY
+CloseNSPerformanceData()
+{
+ instance_list_t *pInstance, *pDead;
+
+ if (!(--dwOpenCount)) {
+
+ for (pDead = NULL, pInstance = pInstanceList; pInstance; pInstance=pInstance->pNext) {
+ if (pDead)
+ free(pDead);
+
+ /* I probably need to free stats too... make sure to add that later */
+ if (pInstance->pData)
+ UnmapSharedMem(&pInstance->pData);
+
+ free(pInstance->pInstanceName);
+ free(pInstance->pConfPath);
+ pDead = pInstance;
+ }
+ if (pDead) /* cleanup last instance */
+ free(pDead);
+
+ MonCloseEventLog();
+
+ bInitialized = FALSE;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+struct _status_struct_s {
+ DWORD connection_rate;
+ DWORD throughput;
+ DWORD tot_bytes_written;
+ DWORD tot_bytes_read;
+ DWORD op_rate;
+ DWORD tot_errs;
+ DWORD search_rate;
+ DWORD add_rate;
+ DWORD delete_rate;
+ DWORD modify_rate;
+ DWORD compare_rate;
+ DWORD moddn_rate;
+ DWORD connections;
+ DWORD bind_rate;
+ DWORD entries_returned;
+ DWORD entries_returned_rate;
+ DWORD referrals_returned;
+ DWORD referrals_returned_rate;
+ DWORD bytes_read_rate;
+ DWORD bytes_written_rate;
+};
+
+void
+Get_Actual_Data(agt_stats_t *smem,
+ struct _status_struct_s *results)
+{
+ /* Copy over the counters from the shared memory region */
+ struct ops_stats_t *pOpsStats = &(smem->ops_stats);
+
+ results->search_rate = pOpsStats->dsSearchOps;
+ results->modify_rate = pOpsStats->dsModifyEntryOps;
+ results->add_rate = pOpsStats->dsAddEntryOps ;
+ results->compare_rate = pOpsStats->dsCompareOps ;
+ results->moddn_rate = pOpsStats->dsModifyRDNOps ;
+ results->delete_rate = pOpsStats->dsRemoveEntryOps ;
+ results->bind_rate = pOpsStats->dsAnonymousBinds + pOpsStats->dsStrongAuthBinds + pOpsStats->dsSimpleAuthBinds ;
+ results->op_rate = results->search_rate + results->add_rate + results->delete_rate +
+ results->modify_rate + results->compare_rate + results->moddn_rate + results->bind_rate;
+ results->connections = 0;
+ results->tot_errs = pOpsStats->dsErrors ;
+ results->connections = pOpsStats->dsConnections ;
+ results->tot_bytes_written = pOpsStats->dsBytesSent ;
+ results->tot_bytes_read = pOpsStats->dsBytesRecv ;
+ results->throughput = pOpsStats->dsBytesSent + pOpsStats->dsBytesRecv;
+ results->connection_rate = pOpsStats->dsConnectionSeq ;
+ results->entries_returned = pOpsStats->dsEntriesReturned ;
+ results->entries_returned_rate = pOpsStats->dsEntriesReturned ;
+ results->referrals_returned = pOpsStats->dsReferralsReturned ;
+ results->referrals_returned_rate = pOpsStats->dsReferralsReturned ;
+ results->bytes_read_rate = pOpsStats->dsBytesRecv ;
+ results->bytes_written_rate = pOpsStats->dsBytesSent ;
+ /* Still to do : connections, throughput, db hit ratio, entry cache hit ratio */
+}
+
+/* --- Collect Function ------------------------------------------------------------------- */
+export DWORD APIENTRY
+CollectNSPerformanceData(
+ IN LPWSTR lpValueName,
+ IN OUT LPVOID *lppData,
+ IN OUT LPDWORD lpcbTotalBytes,
+ IN OUT LPDWORD lpNumObjectTypes
+)
+{
+ ULONG SpaceNeeded;
+ PDWORD pdwCounter;
+ PERF_COUNTER_BLOCK *pPerfCounterBlock;
+ NS_DATA_DEFINITION *pNSDataDefinition;
+ DWORD dwQueryType;
+ instance_list_t *pInstance;
+
+ if (!bInitialized) {
+ *lpcbTotalBytes = (DWORD) 0;
+ *lpNumObjectTypes = (DWORD) 0;
+ return ERROR_SUCCESS;
+ }
+
+ dwQueryType = GetQueryType (lpValueName);
+
+ if (dwQueryType == QUERY_FOREIGN) {
+ // this routine does not service requests for data from
+ // Non-NT computers
+ *lpcbTotalBytes = (DWORD) 0;
+ *lpNumObjectTypes = (DWORD) 0;
+ return ERROR_SUCCESS;
+ }
+
+ if (dwQueryType == QUERY_ITEMS){
+ if ( !(IsNumberInUnicodeList (NSDataDefinition.NS_ObjectType.ObjectNameTitleIndex, lpValueName))) {
+ // request received for data object not provided by this routine
+ *lpcbTotalBytes = (DWORD) 0;
+ *lpNumObjectTypes = (DWORD) 0;
+ return ERROR_SUCCESS;
+ }
+ }
+ /* -------- OK DO THE REAL WORK HERE ---------- */
+
+
+ /* -------------------------------------------- */
+ /* | PERF_DATA_BLOCK (header) | */
+ /* -------------------------------------------- */
+ /* | PERF_OBJECT_TYPE 1 | */
+ /* -------------------------------------------- */
+ /* | PERF_OBJECT_TYPE 2 | */
+ /* -------------------------------------------- */
+ /* | . | */
+ /* | . | */
+ /* | . | */
+ /* | | */
+ /* | | */
+ /* -------------------------------------------- */
+
+
+ /* -------------------------------------------- */
+ /* | PERF_OBJECT_TYPE (header) | */
+ /* -------------------------------------------- */
+ /* | PERF_COUNTER_DEFINITION 1 | */
+ /* -------------------------------------------- */
+ /* | PERF_COUNTER_DEFINITION 2 | */
+ /* -------------------------------------------- */
+ /* | . | */
+ /* | . | */
+ /* | . | */
+ /* | | */
+ /* -------------------------------------------- */
+ /* | PERF_INSTANCE_DEFINITION 1 | */
+ /* -------------------------------------------- */
+ /* | PERF_INSTANCE_DEFINITION 2 | */
+ /* -------------------------------------------- */
+ /* | . | */
+ /* | . | */
+ /* | . | */
+ /* | | */
+ /* | | */
+ /* -------------------------------------------- */
+
+
+ /* -------------------------------------------- */
+ /* | PERF_INSTANCE_DEFINITION (header) | */
+ /* -------------------------------------------- */
+ /* | Instance Name (variable) | */
+ /* -------------------------------------------- */
+ /* | PERF_COUNTER_BLOCK (header) | */
+ /* -------------------------------------------- */
+ /* | Counter Data (variable) | */
+ /* -------------------------------------------- */
+
+
+
+ /* Check to see if there is enough space in caller's buffer */
+
+ pNSDataDefinition = (NS_DATA_DEFINITION *) *lppData;
+
+ SpaceNeeded = sizeof(NS_DATA_DEFINITION) + (dwInstanceCount *
+ (SIZE_OF_NS_PERFORMANCE_DATA + MAX_KEY_SIZE + sizeof(PERF_COUNTER_BLOCK) +
+ sizeof(PERF_INSTANCE_DEFINITION)));
+
+ if ( *lpcbTotalBytes < SpaceNeeded ) {
+ *lpcbTotalBytes = (DWORD) 0;
+ *lpNumObjectTypes = (DWORD) 0;
+ return ERROR_MORE_DATA;
+ }
+
+ /* Set the PERF_OBJECT_TYPE definition and PERF_COUNTER_DEFINITIONs */
+ NSDataDefinition.NS_ObjectType.NumInstances = dwInstanceCount;
+ memmove(pNSDataDefinition, &NSDataDefinition, sizeof(NS_DATA_DEFINITION));
+
+ pdwCounter = (PDWORD) &(pNSDataDefinition[1]);
+
+ for ( pInstance = pInstanceList; pInstance; pInstance=pInstance->pNext) {
+
+ if ( pInstance->pData ) {
+
+ /* Set the PERF_INSTANCE_DEFINITION */
+ memmove(pdwCounter, &(pInstance->instance), sizeof(PERF_INSTANCE_DEFINITION));
+ pdwCounter += ((sizeof(PERF_INSTANCE_DEFINITION))/sizeof(DWORD));
+
+ /* Set the Instance Name */
+ memmove(pdwCounter, pInstance->pInstanceName, pInstance->instance.NameLength);
+ pdwCounter = pdwCounter + ((pInstance->instance.NameLength + sizeof(DWORD)-1)/sizeof(DWORD));
+
+ /* Set the PERF_COUNTER_BLOCK */
+ pPerfCounterBlock = (PERF_COUNTER_BLOCK *) pdwCounter;
+ pPerfCounterBlock->ByteLength = SIZE_OF_NS_PERFORMANCE_DATA + sizeof(PERF_COUNTER_BLOCK);
+ pdwCounter = (PDWORD) (&pPerfCounterBlock[1]);
+
+ /* Set the Instance Data */
+ Get_Actual_Data(pInstance->pData,(struct _status_struct_s*)pdwCounter);
+
+ {
+ DWORD x = (SIZE_OF_NS_PERFORMANCE_DATA) / sizeof(DWORD);
+
+ pdwCounter += x;
+ }
+ }
+ }
+
+ *lppData = (PVOID)(pdwCounter);
+ *lpNumObjectTypes = 1;
+ *lpcbTotalBytes = (PBYTE) pdwCounter - (PBYTE) pNSDataDefinition;
+ pNSDataDefinition->NS_ObjectType.TotalByteLength = *lpcbTotalBytes;
+
+ return ERROR_SUCCESS;
+}
+